dsfa
This commit is contained in:
parent
90e3a4155b
commit
be18980fa5
18 changed files with 336 additions and 62 deletions
6
TODO
6
TODO
|
@ -1,5 +1,7 @@
|
||||||
Bugs:
|
Bugs:
|
||||||
* idle doesnt seem to work?
|
* import quirks from 2.5!
|
||||||
|
* edit quirks?
|
||||||
|
* begin and end regexps should only be applied once!
|
||||||
* X and _ buttons move around all crazy like
|
* X and _ buttons move around all crazy like
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
@ -8,7 +10,6 @@ Features:
|
||||||
* shared buddy lists - changes to the buddy list should refresh it?
|
* shared buddy lists - changes to the buddy list should refresh it?
|
||||||
multiple clients share buddy list???
|
multiple clients share buddy list???
|
||||||
* chumList not scaling -- QListView + delegate?
|
* chumList not scaling -- QListView + delegate?
|
||||||
* spell check?
|
|
||||||
* help button on quirks menu?
|
* help button on quirks menu?
|
||||||
-- release beta
|
-- release beta
|
||||||
* hide offline chums
|
* hide offline chums
|
||||||
|
@ -22,4 +23,3 @@ Features:
|
||||||
* don't clear new message when clicking away from tab?
|
* don't clear new message when clicking away from tab?
|
||||||
* Spy mode
|
* Spy mode
|
||||||
* Animated
|
* Animated
|
||||||
* put code into separate files
|
|
||||||
|
|
5
convo.py
5
convo.py
|
@ -264,9 +264,10 @@ class PesterText(QtGui.QTextEdit):
|
||||||
idlethreshhold = 60
|
idlethreshhold = 60
|
||||||
if (not hasattr(self, 'lastmsg')) or \
|
if (not hasattr(self, 'lastmsg')) or \
|
||||||
datetime.now() - self.lastmsg > timedelta(0,idlethreshhold):
|
datetime.now() - self.lastmsg > timedelta(0,idlethreshhold):
|
||||||
|
verb = window.theme["convo/text/idle"]
|
||||||
idlemsg = me.idlemsg(systemColor, verb)
|
idlemsg = me.idlemsg(systemColor, verb)
|
||||||
self.textArea.append(convertTags(idlemsg))
|
parent.textArea.append(convertTags(idlemsg))
|
||||||
window.chatlog.log(self.title(), idlemsg)
|
window.chatlog.log(parent.title(), idlemsg)
|
||||||
parent.messageSent.emit("PESTERCHUM:IDLE", parent.title())
|
parent.messageSent.emit("PESTERCHUM:IDLE", parent.title())
|
||||||
self.lastmsg = datetime.now()
|
self.lastmsg = datetime.now()
|
||||||
window.chatlog.log(chum.handle, lexmsg)
|
window.chatlog.log(chum.handle, lexmsg)
|
||||||
|
|
BIN
convo.pyc
BIN
convo.pyc
Binary file not shown.
24
dataobjs.py
24
dataobjs.py
|
@ -4,7 +4,7 @@ import re
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from generic import PesterIcon
|
from generic import PesterIcon
|
||||||
from parsetools import timeDifference, convertTags
|
from parsetools import timeDifference, convertTags, lexMessage
|
||||||
from mispeller import mispeller
|
from mispeller import mispeller
|
||||||
|
|
||||||
_upperre = re.compile(r"upper\(([\w\\]+)\)")
|
_upperre = re.compile(r"upper\(([\w\\]+)\)")
|
||||||
|
@ -116,7 +116,7 @@ class pesterQuirks(object):
|
||||||
suffix = [q for q in self.quirklist if q.type=='suffix']
|
suffix = [q for q in self.quirklist if q.type=='suffix']
|
||||||
replace = [q for q in self.quirklist if
|
replace = [q for q in self.quirklist if
|
||||||
q.type=='replace' or q.type=='regexp']
|
q.type=='replace' or q.type=='regexp']
|
||||||
random = [q for q in self.quirklist if q.type=='random']
|
randomrep = [q for q in self.quirklist if q.type=='random']
|
||||||
spelling = [q for q in self.quirklist if q.type=='spelling']
|
spelling = [q for q in self.quirklist if q.type=='spelling']
|
||||||
|
|
||||||
newlist = []
|
newlist = []
|
||||||
|
@ -133,19 +133,27 @@ class pesterQuirks(object):
|
||||||
string = o
|
string = o
|
||||||
for s in spelling:
|
for s in spelling:
|
||||||
string = s.apply(string)
|
string = s.apply(string)
|
||||||
for r in random:
|
for r in randomrep:
|
||||||
string = r.apply(string, first=(i==0), last=lastStr)
|
string = r.apply(string, first=(i==0), last=lastStr)
|
||||||
for r in replace:
|
for r in replace:
|
||||||
string = r.apply(string, first=(i==0), last=lastStr)
|
string = r.apply(string, first=(i==0), last=lastStr)
|
||||||
if i == 0:
|
if i == 0:
|
||||||
for p in prefix:
|
if len(prefix) >= 1:
|
||||||
string = p.apply(string)
|
myprefix = random.choice(prefix)
|
||||||
|
string = myprefix.apply(string)
|
||||||
if lastStr:
|
if lastStr:
|
||||||
for s in suffix:
|
if len(suffix) >= 1:
|
||||||
string = s.apply(string)
|
mysuffix = random.choice(suffix)
|
||||||
|
string = mysuffix.apply(string)
|
||||||
newlist.append(string)
|
newlist.append(string)
|
||||||
|
|
||||||
return newlist
|
final = []
|
||||||
|
for n in newlist:
|
||||||
|
if type(n) in [str, unicode]:
|
||||||
|
final.extend(lexMessage(n))
|
||||||
|
else:
|
||||||
|
final.append(n)
|
||||||
|
return final
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for q in self.quirklist:
|
for q in self.quirklist:
|
||||||
|
|
BIN
dataobjs.pyc
BIN
dataobjs.pyc
Binary file not shown.
26
irc.py
26
irc.py
|
@ -16,22 +16,29 @@ class PesterIRC(QtCore.QThread):
|
||||||
QtCore.QThread.__init__(self)
|
QtCore.QThread.__init__(self)
|
||||||
self.mainwindow = window
|
self.mainwindow = window
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.registeredIRC = False
|
||||||
|
self.stopIRC = None
|
||||||
def IRCConnect(self):
|
def IRCConnect(self):
|
||||||
server = self.config.server()
|
server = self.config.server()
|
||||||
port = self.config.port()
|
port = self.config.port()
|
||||||
self.cli = IRCClient(PesterHandler, host=server, port=int(port), nick=self.mainwindow.profile().handle, real_name='pcc30', blocking=True, timeout=5)
|
self.cli = IRCClient(PesterHandler, host=server, port=int(port), nick=self.mainwindow.profile().handle, real_name='pcc30', blocking=True, timeout=15)
|
||||||
self.cli.command_handler.parent = self
|
self.cli.command_handler.parent = self
|
||||||
self.cli.command_handler.mainwindow = self.mainwindow
|
self.cli.command_handler.mainwindow = self.mainwindow
|
||||||
self.conn = self.cli.connect()
|
self.cli.connect()
|
||||||
self.stopIRC = None
|
self.conn = self.cli.conn()
|
||||||
self.registeredIRC = False
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.IRCConnect()
|
try:
|
||||||
|
self.IRCConnect()
|
||||||
|
except socket.error, se:
|
||||||
|
self.stopIRC = se
|
||||||
|
return
|
||||||
while 1:
|
while 1:
|
||||||
|
res = True
|
||||||
try:
|
try:
|
||||||
|
logging.debug("updateIRC()")
|
||||||
res = self.updateIRC()
|
res = self.updateIRC()
|
||||||
except socket.timeout, se:
|
except socket.timeout, se:
|
||||||
print "timeout in thread %s" % (self)
|
logging.debug("timeout in thread %s" % (self))
|
||||||
self.cli.close()
|
self.cli.close()
|
||||||
self.stopIRC = se
|
self.stopIRC = se
|
||||||
return
|
return
|
||||||
|
@ -40,16 +47,18 @@ class PesterIRC(QtCore.QThread):
|
||||||
self.stopIRC = None
|
self.stopIRC = None
|
||||||
else:
|
else:
|
||||||
self.stopIRC = se
|
self.stopIRC = se
|
||||||
|
logging.debug("socket error, exiting thread")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if not res:
|
if not res:
|
||||||
|
logging.debug("false Yield: %s, returning" % res)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setConnected(self):
|
def setConnected(self):
|
||||||
self.registeredIRC = True
|
self.registeredIRC = True
|
||||||
self.connected.emit()
|
self.connected.emit()
|
||||||
def setConnectionBroken(self):
|
def setConnectionBroken(self):
|
||||||
print "setconnection broken"
|
logging.debug("setconnection broken")
|
||||||
self.reconnectIRC()
|
self.reconnectIRC()
|
||||||
#self.brokenConnection = True
|
#self.brokenConnection = True
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
|
@ -64,12 +73,13 @@ class PesterIRC(QtCore.QThread):
|
||||||
except socket.error, se:
|
except socket.error, se:
|
||||||
raise se
|
raise se
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
self.conn = self.cli.conn()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return res
|
return res
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def reconnectIRC(self):
|
def reconnectIRC(self):
|
||||||
print "reconnectIRC() from thread %s" % (self)
|
logging.debug("reconnectIRC() from thread %s" % (self))
|
||||||
self.cli.close()
|
self.cli.close()
|
||||||
|
|
||||||
@QtCore.pyqtSlot(PesterProfile)
|
@QtCore.pyqtSlot(PesterProfile)
|
||||||
|
|
BIN
irc.pyc
BIN
irc.pyc
Binary file not shown.
File diff suppressed because one or more lines are too long
7
menus.py
7
menus.py
|
@ -652,11 +652,16 @@ class LoadingScreen(QtGui.QDialog):
|
||||||
self.layout.addLayout(layout_1)
|
self.layout.addLayout(layout_1)
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
|
|
||||||
|
def hideReconnect(self):
|
||||||
|
self.ok.hide()
|
||||||
|
def showReconnect(self):
|
||||||
|
self.ok.show()
|
||||||
|
|
||||||
tryAgain = QtCore.pyqtSignal()
|
tryAgain = QtCore.pyqtSignal()
|
||||||
|
|
||||||
class AboutPesterchum(QtGui.QMessageBox):
|
class AboutPesterchum(QtGui.QMessageBox):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QtGui.QMessageBox.__init__(self, parent)
|
QtGui.QMessageBox.__init__(self, parent)
|
||||||
self.setText("P3ST3RCHUM V. 3.14 alpha 4")
|
self.setText("P3ST3RCHUM V. 3.14 alpha 6")
|
||||||
self.setInformativeText("Programming by illuminatedwax (ghostDunk), art by Grimlive (aquaMarinist)")
|
self.setInformativeText("Programming by illuminatedwax (ghostDunk), art by Grimlive (aquaMarinist)")
|
||||||
self.mainwindow = parent
|
self.mainwindow = parent
|
||||||
|
|
BIN
menus.pyc
BIN
menus.pyc
Binary file not shown.
|
@ -93,7 +93,7 @@ class IRCClient:
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(kwargs)
|
||||||
self.command_handler = cmd_handler(self)
|
self.command_handler = cmd_handler(self)
|
||||||
|
|
||||||
self._end = 0
|
self._end = False
|
||||||
|
|
||||||
def send(self, *args, **kwargs):
|
def send(self, *args, **kwargs):
|
||||||
""" send a message to the connected server. all arguments are joined
|
""" send a message to the connected server. all arguments are joined
|
||||||
|
@ -139,29 +139,23 @@ class IRCClient:
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
""" initiates the connection to the server set in self.host:self.port
|
""" initiates the connection to the server set in self.host:self.port
|
||||||
and returns a generator object.
|
|
||||||
|
|
||||||
>>> cli = IRCClient(my_handler, host="irc.freenode.net", port=6667)
|
|
||||||
>>> g = cli.connect()
|
|
||||||
>>> while 1:
|
|
||||||
... g.next()
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
#logfile = open('irctest.log', 'a')
|
|
||||||
|
|
||||||
try:
|
logging.info('connecting to %s:%s' % (self.host, self.port))
|
||||||
logging.info('connecting to %s:%s' % (self.host, self.port))
|
self.socket.connect(("%s" % self.host, self.port))
|
||||||
self.socket.connect(("%s" % self.host, self.port))
|
if not self.blocking:
|
||||||
if not self.blocking:
|
self.socket.setblocking(0)
|
||||||
self.socket.setblocking(0)
|
if self.timeout:
|
||||||
if self.timeout:
|
self.socket.settimeout(self.timeout)
|
||||||
self.socket.settimeout(self.timeout)
|
helpers.nick(self, self.nick)
|
||||||
helpers.nick(self, self.nick)
|
helpers.user(self, self.nick, self.real_name)
|
||||||
helpers.user(self, self.nick, self.real_name)
|
|
||||||
|
|
||||||
if self.connect_cb:
|
if self.connect_cb:
|
||||||
self.connect_cb(self)
|
self.connect_cb(self)
|
||||||
|
|
||||||
|
def conn(self):
|
||||||
|
"""returns a generator object. """
|
||||||
|
try:
|
||||||
buffer = bytes()
|
buffer = bytes()
|
||||||
while not self._end:
|
while not self._end:
|
||||||
try:
|
try:
|
||||||
|
@ -169,12 +163,12 @@ class IRCClient:
|
||||||
except socket.timeout, e:
|
except socket.timeout, e:
|
||||||
if self._end:
|
if self._end:
|
||||||
break
|
break
|
||||||
print "timeout in client.py"
|
logging.debug("timeout in client.py")
|
||||||
raise e
|
raise e
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
if self._end:
|
if self._end:
|
||||||
break
|
break
|
||||||
print "error %s" % e
|
logging.debug("error %s" % e)
|
||||||
try: # a little dance of compatibility to get the errno
|
try: # a little dance of compatibility to get the errno
|
||||||
errno = e.errno
|
errno = e.errno
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -202,14 +196,19 @@ class IRCClient:
|
||||||
|
|
||||||
yield True
|
yield True
|
||||||
except socket.timeout, se:
|
except socket.timeout, se:
|
||||||
|
logging.debug("passing timeout")
|
||||||
raise se
|
raise se
|
||||||
except socket.error, se:
|
except socket.error, se:
|
||||||
print "problem: %s" % (se)
|
logging.debug("problem: %s" % (se))
|
||||||
if self.socket:
|
if self.socket:
|
||||||
logging.info('error: closing socket')
|
logging.info('error: closing socket')
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
raise se
|
raise se
|
||||||
|
except Exception, e:
|
||||||
|
logging.debug("other exception: %s" % e)
|
||||||
|
raise e
|
||||||
else:
|
else:
|
||||||
|
logging.debug("ending while, end is %s" % self._end)
|
||||||
if self.socket:
|
if self.socket:
|
||||||
logging.info('finished: closing socket')
|
logging.info('finished: closing socket')
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
|
|
BIN
oyoyo/client.pyc
BIN
oyoyo/client.pyc
Binary file not shown.
|
@ -151,6 +151,8 @@ def lexMessage(string):
|
||||||
if beginc > endc:
|
if beginc > endc:
|
||||||
for i in range(0, beginc-endc):
|
for i in range(0, beginc-endc):
|
||||||
balanced.append(colorEnd("</c>"))
|
balanced.append(colorEnd("</c>"))
|
||||||
|
if len(balanced) == 0:
|
||||||
|
balanced.append("")
|
||||||
if type(balanced[len(balanced)-1]) not in [str, unicode]:
|
if type(balanced[len(balanced)-1]) not in [str, unicode]:
|
||||||
balanced.append("")
|
balanced.append("")
|
||||||
return balanced
|
return balanced
|
||||||
|
|
BIN
parsetools.pyc
BIN
parsetools.pyc
Binary file not shown.
|
@ -1 +1 @@
|
||||||
{"tabs": false, "soundon": true, "server": "irc.tymoon.eu", "chums": ["unknownTraveler", "tentacleTherapist", "vaginalEngineer", "mechanicalSpectacle", "carcinoGeneticist", "schlagzeugGator", "gamblingGenocider", "gardenGnostic", "superGhost", "centaursTesticle", "arachnidsGrip", "grimAuxiliatrix", "remoteBloodbath", "nitroZealist", "greenZephyr", "arsenicCatnip", "adiosToreador", "cuttlefishCuller", "rageInducer", "gallowsCalibrator", "caligulasAquarium", "terminallyCapricious", "illuminatedWax", "aquaMarinist", "elegantDiversion", "moirailBunp", "uroborosUnbound", "androidTechnician", "midnightSparrow", "apocalypseArisen", "anguillaNuntia", "oilslickOrchid", "confusedTransient", "pretentiousFantasia", "aquaticMarinist", "lyricalKeraunoscopic", "counterRealist", "ectoBiologist", "percipientPedestrian", "asceticClinician", "doctectiveMiracles", "noSense", "obliviousCrafter", "ircMonster", "twinArmageddons", "cannabisHero"], "defaultprofile": "ghostDunk", "block": []}
|
{"tabs": true, "soundon": true, "server": "irc.tymoon.eu", "chums": ["unknownTraveler", "tentacleTherapist", "vaginalEngineer", "mechanicalSpectacle", "carcinoGeneticist", "schlagzeugGator", "gamblingGenocider", "gardenGnostic", "superGhost", "centaursTesticle", "arachnidsGrip", "grimAuxiliatrix", "remoteBloodbath", "nitroZealist", "greenZephyr", "arsenicCatnip", "adiosToreador", "cuttlefishCuller", "rageInducer", "gallowsCalibrator", "caligulasAquarium", "terminallyCapricious", "illuminatedWax", "aquaMarinist", "elegantDiversion", "moirailBunp", "uroborosUnbound", "androidTechnician", "midnightSparrow", "apocalypseArisen", "anguillaNuntia", "oilslickOrchid", "confusedTransient", "pretentiousFantasia", "aquaticMarinist", "lyricalKeraunoscopic", "counterRealist", "ectoBiologist", "percipientPedestrian", "asceticClinician", "doctectiveMiracles", "noSense", "obliviousCrafter", "ircMonster", "twinArmageddons", "cannabisHero", "jetRocket"], "defaultprofile": "ghostDunk", "block": []}
|
|
@ -1138,8 +1138,10 @@ class PesterWindow(MovingWindow):
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def connected(self):
|
def connected(self):
|
||||||
|
print "CONNECTED!"
|
||||||
|
print self.loadingscreen
|
||||||
if self.loadingscreen:
|
if self.loadingscreen:
|
||||||
self.loadingscreen.accept()
|
self.loadingscreen.done(QtGui.QDialog.Accepted)
|
||||||
self.loadingscreen = None
|
self.loadingscreen = None
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def blockSelectedChum(self):
|
def blockSelectedChum(self):
|
||||||
|
@ -1352,6 +1354,8 @@ class PesterWindow(MovingWindow):
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def importExternalConfig(self):
|
def importExternalConfig(self):
|
||||||
f = QtGui.QFileDialog.getOpenFileName(self)
|
f = QtGui.QFileDialog.getOpenFileName(self)
|
||||||
|
if f == "":
|
||||||
|
return
|
||||||
fp = open(f, 'r')
|
fp = open(f, 'r')
|
||||||
for l in fp.xreadlines():
|
for l in fp.xreadlines():
|
||||||
# import chumlist
|
# import chumlist
|
||||||
|
@ -1802,24 +1806,42 @@ class MainProgram(QtCore.QObject):
|
||||||
|
|
||||||
def showLoading(self, widget, msg="CONN3CT1NG"):
|
def showLoading(self, widget, msg="CONN3CT1NG"):
|
||||||
self.widget.show()
|
self.widget.show()
|
||||||
self.widget.activateWindow()
|
if hasattr(self.widget, 'loadingscreen') and widget.loadingscreen:
|
||||||
widget.loadingscreen = LoadingScreen(widget)
|
widget.loadingscreen.loadinglabel.setText(msg)
|
||||||
widget.loadingscreen.loadinglabel.setText(msg)
|
if self.reconnectok:
|
||||||
self.connect(widget.loadingscreen, QtCore.SIGNAL('rejected()'),
|
widget.loadingscreen.showReconnect()
|
||||||
widget, QtCore.SLOT('close()'))
|
else:
|
||||||
self.connect(self.widget.loadingscreen, QtCore.SIGNAL('tryAgain()'),
|
widget.loadingscreen.hideReconnect()
|
||||||
self, QtCore.SLOT('tryAgain()'))
|
else:
|
||||||
status = widget.loadingscreen.exec_()
|
widget.loadingscreen = LoadingScreen(widget)
|
||||||
if status == QtGui.QDialog.Rejected:
|
widget.loadingscreen.loadinglabel.setText(msg)
|
||||||
sys.exit(0)
|
self.connect(widget.loadingscreen, QtCore.SIGNAL('rejected()'),
|
||||||
|
widget, QtCore.SLOT('close()'))
|
||||||
|
self.connect(self.widget.loadingscreen, QtCore.SIGNAL('tryAgain()'),
|
||||||
|
self, QtCore.SLOT('tryAgain()'))
|
||||||
|
if hasattr(self, 'irc') and self.irc.registeredIRC:
|
||||||
|
return
|
||||||
|
if self.reconnectok:
|
||||||
|
widget.loadingscreen.showReconnect()
|
||||||
|
else:
|
||||||
|
widget.loadingscreen.hideReconnect()
|
||||||
|
status = widget.loadingscreen.exec_()
|
||||||
|
print "exited with status %d" % status
|
||||||
|
if status == QtGui.QDialog.Rejected:
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def connected(self):
|
def connected(self):
|
||||||
self.attempts = 0
|
self.attempts = 0
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def tryAgain(self):
|
def tryAgain(self):
|
||||||
|
if not self.reconnectok:
|
||||||
|
return
|
||||||
if self.widget.loadingscreen:
|
if self.widget.loadingscreen:
|
||||||
self.widget.loadingscreen.accept()
|
self.widget.loadingscreen.done(QtGui.QDialog.Accepted)
|
||||||
|
self.widget.loadingscreen = None
|
||||||
self.attempts += 1
|
self.attempts += 1
|
||||||
if hasattr(self, 'irc') and self.irc:
|
if hasattr(self, 'irc') and self.irc:
|
||||||
print "tryagain: reconnectIRC()"
|
print "tryagain: reconnectIRC()"
|
||||||
|
@ -1827,17 +1849,18 @@ class MainProgram(QtCore.QObject):
|
||||||
print "finishing"
|
print "finishing"
|
||||||
self.irc.quit()
|
self.irc.quit()
|
||||||
else:
|
else:
|
||||||
print "tryagain: restartIRC"
|
print "tryagain: restartIRC()"
|
||||||
self.restartIRC()
|
self.restartIRC()
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def restartIRC(self):
|
def restartIRC(self):
|
||||||
if hasattr(self, 'irc') and self.irc:
|
if hasattr(self, 'irc') and self.irc:
|
||||||
|
print "deleting IRC"
|
||||||
self.disconnectWidgets(self.irc, self.widget)
|
self.disconnectWidgets(self.irc, self.widget)
|
||||||
stop = self.irc.stopIRC
|
stop = self.irc.stopIRC
|
||||||
del self.irc
|
del self.irc
|
||||||
else:
|
else:
|
||||||
stop = None
|
stop = None
|
||||||
if not stop:
|
if stop is None:
|
||||||
self.irc = PesterIRC(self.widget.config, self.widget)
|
self.irc = PesterIRC(self.widget.config, self.widget)
|
||||||
self.connectWidgets(self.irc, self.widget)
|
self.connectWidgets(self.irc, self.widget)
|
||||||
self.irc.start()
|
self.irc.start()
|
||||||
|
@ -1847,12 +1870,16 @@ class MainProgram(QtCore.QObject):
|
||||||
msg = "R3CONN3CT1NG %d" % (self.attempts)
|
msg = "R3CONN3CT1NG %d" % (self.attempts)
|
||||||
else:
|
else:
|
||||||
msg = "CONN3CT1NG"
|
msg = "CONN3CT1NG"
|
||||||
|
print "loadingscreen: auto reconnect"
|
||||||
|
self.reconnectok = False
|
||||||
self.showLoading(self.widget, msg)
|
self.showLoading(self.widget, msg)
|
||||||
else:
|
else:
|
||||||
|
self.reconnectok = True
|
||||||
self.showLoading(self.widget, "F41L3D: %s" % stop)
|
self.showLoading(self.widget, "F41L3D: %s" % stop)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.irc.start()
|
self.irc.start()
|
||||||
|
self.reconnectok = False
|
||||||
self.showLoading(self.widget)
|
self.showLoading(self.widget)
|
||||||
sys.exit(self.app.exec_())
|
sys.exit(self.app.exec_())
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"color": "#ff00ff", "theme": "pesterchum2.5", "quirks": [], "handle": "ghostDunk"}
|
{"color": "#ff00ff", "theme": "pesterchum", "quirks": [], "handle": "ghostDunk"}
|
222
readme.txt
222
readme.txt
|
@ -98,6 +98,228 @@ CG: #FRUITYRUMPUSASSHOLEFACTORY
|
||||||
and it will appear as a link that you can click, which will open the
|
and it will appear as a link that you can click, which will open the
|
||||||
memo chooser window.
|
memo chooser window.
|
||||||
|
|
||||||
|
QUIRKS
|
||||||
|
------
|
||||||
|
There are six kinds of quirks! I'll teach you how to use them all!
|
||||||
|
(In this section, I will use quotes ("") around things so it's clearer
|
||||||
|
to see exactly what to type! Don't include these quotes when using
|
||||||
|
these examples!
|
||||||
|
|
||||||
|
Prefix/Suffix: This will put text before or after everything you
|
||||||
|
say. So for example, we can use prefixes to emulate part of Nepeta or
|
||||||
|
Equius' quirks:
|
||||||
|
|
||||||
|
PREFIX: ":33 < "
|
||||||
|
You type: "*ac twitches her friendly whiskers at ct*"
|
||||||
|
Result:
|
||||||
|
AC: :33 < *ac twitches her friendly whiskers at ct*
|
||||||
|
|
||||||
|
PREFIX: "D --> "
|
||||||
|
You type: "Hi"
|
||||||
|
Result:
|
||||||
|
CT: D --> Hi
|
||||||
|
|
||||||
|
Suffixes work the same way, but at the end of the message:
|
||||||
|
SUFFIX: "!!!"
|
||||||
|
You type: hey there
|
||||||
|
Result:
|
||||||
|
GD: hey there!!!
|
||||||
|
|
||||||
|
Remember that it doesn't automatically add a space! You'll need to add
|
||||||
|
it in (see CT and AC examples again!)
|
||||||
|
|
||||||
|
Simple Replace:
|
||||||
|
This will simply take a set of characters and replace them with other
|
||||||
|
characters. Let's add a quirk to our Nepeta:
|
||||||
|
|
||||||
|
Replace: "ee" With: "33"
|
||||||
|
You type: "*ac saunters from her dark cave a little bit sleepy from
|
||||||
|
the recent kill*"
|
||||||
|
Result:
|
||||||
|
AC: :33 < *ac saunters from her dark cave a little bit sl33py from the
|
||||||
|
recent kill*
|
||||||
|
|
||||||
|
Let's add two to Equius:
|
||||||
|
Replace: "loo" With: "100"
|
||||||
|
Replace: "x" With "%"
|
||||||
|
You type: "look"
|
||||||
|
Result:
|
||||||
|
CT: D --> 100k
|
||||||
|
You type: "What are you expecting to accomplish with this"
|
||||||
|
Result:
|
||||||
|
CT: D --> What are you e%pecting to accomplish with this
|
||||||
|
|
||||||
|
Aradia:
|
||||||
|
Replace: "o" With: "0"
|
||||||
|
You type: "and the reward would be within our reach"
|
||||||
|
Result:
|
||||||
|
AA: and the reward w0uld be within 0ur reach
|
||||||
|
|
||||||
|
Notice that it is CASE SENSITIVE. So in the above case, if you typed
|
||||||
|
"ABSCOND", it would not replace the "O".
|
||||||
|
|
||||||
|
Sollux:
|
||||||
|
Replace: "i" With: "ii"
|
||||||
|
Replace: "s" With: "2"
|
||||||
|
|
||||||
|
Eridan:
|
||||||
|
Replace: "v" With: "vv"
|
||||||
|
Replace: "w" With: "ww"
|
||||||
|
|
||||||
|
Feferi:
|
||||||
|
Replace: "h" with: ")("
|
||||||
|
Replace: "H" with: ")("
|
||||||
|
Replace: "E" with: "-E"
|
||||||
|
|
||||||
|
Regexp Replace:
|
||||||
|
|
||||||
|
This is a more complex kind of replacement. Regexp stands for "regular
|
||||||
|
expression", a kind of programming language (yes, it is a language)
|
||||||
|
used to find and replace text. PC 3.14 also includes a function to
|
||||||
|
handle capitalization (upper()). If you want to learn it on your own,
|
||||||
|
I suggest you start with the Python tutorial
|
||||||
|
(http://docs.python.org/howto/regex.html) since PC 3.14 uses Python's
|
||||||
|
regexps. Check out V2.5's tutorial too, as that is a pretty good start
|
||||||
|
as well.
|
||||||
|
|
||||||
|
Let's start with Karkat. Regexps are just like your every day find and
|
||||||
|
replace: they search for a string that matches what you want to
|
||||||
|
replace, and replaces it with... the replacement.
|
||||||
|
|
||||||
|
Regexp: "(.)" Replace with: "upper(\1)"
|
||||||
|
|
||||||
|
Three concepts here. Let's look at the regexp. "(.)" has two things
|
||||||
|
going on. The first is that ".". In regexp speak, "." is the wildcard:
|
||||||
|
it will match *any* character -- and just one.
|
||||||
|
|
||||||
|
The parentheses tell the regexp to *save* what's inside them so you
|
||||||
|
can put it back when you replace. That's what the "\1" is for -- it
|
||||||
|
means, "put the match inside parentheses #1 here". You can have any
|
||||||
|
number of parentheses.
|
||||||
|
|
||||||
|
"upper()" is a function special to PC 3.14 -- it will uppercase
|
||||||
|
anything inside the parentheses. So in this case, upper will uppercase
|
||||||
|
"\1" -- which, as you recall is what we found inside the
|
||||||
|
parentheses. Which was *every* character. So to sum up, it replaces
|
||||||
|
every character with an uppercase version of that character. WHICH
|
||||||
|
MAKES YOU TALK LIKE THIS.
|
||||||
|
|
||||||
|
Let's look at Terezi next.
|
||||||
|
|
||||||
|
Regexp: "[aA]" Replace with: "4"
|
||||||
|
Regexp: "[iI]" Replace with: "1"
|
||||||
|
Regexp: "[eE]" Replace with: "3"
|
||||||
|
Regexp: "(.)" Replace with: "upper(\1)"
|
||||||
|
|
||||||
|
We already know what the last line does. But what's up with those
|
||||||
|
brackets? What's their deal? Basically, in regular expressions,
|
||||||
|
brackets indicate a list of matching characters. So, basically any
|
||||||
|
single character within the brackets will be matched. In this case,
|
||||||
|
either "a" or "A" will be matched and replaced with "4," and likewise,
|
||||||
|
"i" and "I" will be replaced with "1", and "e" and "E" will be
|
||||||
|
replaced with "3."
|
||||||
|
|
||||||
|
You should also know that "^" is a special character in brackets. If
|
||||||
|
placed immediately after the opening bracket (like "[^"), then the
|
||||||
|
brackets instead match every character *except* the ones in the
|
||||||
|
brackets. So, for example, if you wanted to have a quirk where you
|
||||||
|
capitalized all your letters *except* o, you'd do this:
|
||||||
|
|
||||||
|
Regexp: "([^o])" Replace with: "upper(\1)"
|
||||||
|
You type: "hello there"
|
||||||
|
Result:
|
||||||
|
GD: HELLo THERE
|
||||||
|
|
||||||
|
You can also specify a *range* of characters inside the brackets, by
|
||||||
|
using the "-" character. [a-z] will match any lowercase letter. You
|
||||||
|
can combine them, too: [a-z0-9] will match any digit and lowercase letter.
|
||||||
|
|
||||||
|
There are also different shortcuts for character types:
|
||||||
|
|
||||||
|
\d matches any digit; same as [0-9]
|
||||||
|
\D matches any non-digit; same as [^0-9]
|
||||||
|
\s matches any spaces
|
||||||
|
\S matches any non-space
|
||||||
|
\w matches any alphanumeric character; same as [a-zA-Z0-9_]
|
||||||
|
\W matches any non-alphanumeric character; same as [^a-zA-Z0-9_]
|
||||||
|
|
||||||
|
You can include this inside brackets, too.
|
||||||
|
|
||||||
|
There's also a special character, \b. What \b does is make sure that
|
||||||
|
you are at the beginning or end of a word. So with that knowledge,
|
||||||
|
let's try Kanaya:
|
||||||
|
|
||||||
|
Regexp: \b(\w) Replace with: upper(\1)
|
||||||
|
You type: "i suggest you come to terms with it"
|
||||||
|
Result:
|
||||||
|
GA: I Suggest You Come To Terms With It
|
||||||
|
|
||||||
|
Another feature of regular expressions is the ability to match
|
||||||
|
*repeated* characters. There are three repeat characters: the "*", the
|
||||||
|
"+", "?", and "{m,n}". They work by playing them after the character,
|
||||||
|
or character type you want to match. (So, you could say "\s+" or ".*")
|
||||||
|
|
||||||
|
The "*" character matches ZERO or more of that character. So, for
|
||||||
|
example, "f*" would match "f" and "ff" -- and any other character!
|
||||||
|
That's right, every character counts as matching it zero times. Yeah,
|
||||||
|
it's weird. I suggest you use...
|
||||||
|
|
||||||
|
The "+" character matches ONE or more of that character. So, if we
|
||||||
|
wanted to have a character that wanted to elongate their s's so that
|
||||||
|
they used four 's's every time, like sssso, but didn't want to have
|
||||||
|
eight s's when using words with double s's, like pass, we'd do this:
|
||||||
|
|
||||||
|
Regexp: "s+" Replace with: "ssss"
|
||||||
|
You type: "you shall not pass"
|
||||||
|
Result:
|
||||||
|
UU: you sssshall not passss
|
||||||
|
|
||||||
|
As for the other two, I can't really think of any useful quirks to be
|
||||||
|
made with them. But to let you know, "?" matches either 0 or 1 of that
|
||||||
|
character, so "trolls?" would match "troll" and "trolls". "{m,n}"
|
||||||
|
matches between m and n characters. (If you leave out 'n', any number
|
||||||
|
of characters more than m will be matched.) So "s{2,4}" will match
|
||||||
|
"ss", "sss", and "ssss" and that's it.
|
||||||
|
|
||||||
|
Now with repeating expressions, we can do something like make EVERY
|
||||||
|
other WORD capitalized:
|
||||||
|
|
||||||
|
Regexp: "(\w+) (\w+)" Replace with: "upper(\1) \2"
|
||||||
|
You type: "this is pretty annoying i bet"
|
||||||
|
Result:
|
||||||
|
GD: THIS is PRETTY annoying I bet
|
||||||
|
|
||||||
|
The \1 matches the first word -- which has been matched because the
|
||||||
|
word is alphanumeric characters, repeated once or more -- and \2
|
||||||
|
matches the second word.
|
||||||
|
|
||||||
|
Another operator to use is the "|", which will match more than one set
|
||||||
|
of characters. For example, "black|red" will match "black" or
|
||||||
|
"red". If you want to match something in the middle of words, you have
|
||||||
|
to use parentheses: "(black|red) romance" will match "black romance"
|
||||||
|
and "red romance".
|
||||||
|
|
||||||
|
Finally, there are the "^" and "$" characters. Yes, we already did the
|
||||||
|
"^" character, but this is OUTSIDE of brackets, not INSIDE. "^"
|
||||||
|
matches the beginning of a message, and "$" matches the end of it. You
|
||||||
|
can use this to make more sophisticated prefix and suffix
|
||||||
|
behaviors. For example, if we have a quirk that adds "..." to the end
|
||||||
|
of all our messages, we can set it up so it doesn't do that if we put
|
||||||
|
punctuation [?!.] at the end. So:
|
||||||
|
|
||||||
|
Regexp: "([^?!.])$" Replace with: "\1..."
|
||||||
|
|
||||||
|
This will match the end of any message as long as it doesn't have
|
||||||
|
"?", "!", or "." at the end. Then it will replace it with whatever the
|
||||||
|
last character of the sentence was (remember we're replacing it, so we
|
||||||
|
have to put it back!) and add "..." at the end.
|
||||||
|
|
||||||
|
Careful with the beginning and ending replaces -- if you use more than
|
||||||
|
one, you may not get what you expect because they will ALL be applied,
|
||||||
|
one after the other! This is a bug in my opinion, that I plan to fix!
|
||||||
|
|
||||||
|
Random replace:
|
||||||
|
|
||||||
SMILIES
|
SMILIES
|
||||||
-------
|
-------
|
||||||
Here's a list of smilies:
|
Here's a list of smilies:
|
||||||
|
|
Loading…
Reference in a new issue