Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Zielke <kg4gjy@takeovertheworld.org>2009-05-26 05:16:33 (GMT)
committer Jack Zielke <kg4gjy@takeovertheworld.org>2009-05-26 05:16:33 (GMT)
commit430617045da709023a9f2cc9f4bffdecd3c3728a (patch)
treeb498138c710d5b7b834529a7ce2ff8ec9a66eed5
parent9d5629af4687c6c8d08ccdb961c21573b74b82a6 (diff)
version 5 - no journal, can not cancel messages
-rw-r--r--NEWS1
-rw-r--r--TODO1
-rw-r--r--activity/activity.info2
-rwxr-xr-xaprs.py309
4 files changed, 174 insertions, 139 deletions
diff --git a/NEWS b/NEWS
index c64a9df..21c5b6f 100644
--- a/NEWS
+++ b/NEWS
@@ -3,3 +3,4 @@ September 20 2008 - version 1 - no journal, no messaging
September 22 2008 - version 2 - no journal, can not send messages, gui update
September 25 2008 - version 3 - no journal, can not send messages, gui update
September 28 2008 - version 4 - no journal, no message queue, gui update
+October 5 2008 - version 5 - no journal, can not cancel messages
diff --git a/TODO b/TODO
index a23850b..ca8ab62 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
save in journal
-send messages
multi language
cleanup timers on disconnect
diff --git a/activity/activity.info b/activity/activity.info
index 7c99a2c..34c38f0 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,6 +1,6 @@
[Activity]
name = APRS-XO
-activity_version= 4
+activity_version= 5
service_name = org.laptop.APRSXO
icon = activity-aprs-xo
exec = sugar-activity aprs.APRSActivity
diff --git a/aprs.py b/aprs.py
index f60ad04..b037c5b 100755
--- a/aprs.py
+++ b/aprs.py
@@ -40,6 +40,8 @@ RECV_BUFFER = 4096
MAXLINES = 50
MAXRETRIES = 15
+MAX_MSG_QUEUE = 10
+MAX_PER_CALL_QUEUE = 2
bundle = ActivityBundle(activity.get_bundle_path())
VERSION = bundle.get_activity_version()
@@ -61,6 +63,10 @@ class APRSActivity(activity.Activity):
self.help = True
self.messagebox = False
self.sequence = random.randrange(0, 7000)
+ self.queue_list = {}
+ self.message_list = {}
+ self.seen_bulletins = {}
+ self.message_marks = {}
titlefont = pango.FontDescription('Sans bold 8')
mediumfont = pango.FontDescription('Sans 6.5')
@@ -168,7 +174,7 @@ class APRSActivity(activity.Activity):
bottomidentbox = gtk.HBox(False, 10)
calllabel1 = gtk.Label("Callsign: ")
- calllabel1.set_alignment(0, 0.5)
+ calllabel1.set_alignment(1, 0.5)
bottomidentbox.pack_start(calllabel1, False, False, 0)
calllabel1.show()
@@ -180,7 +186,7 @@ class APRSActivity(activity.Activity):
self.calltext.show()
passlabel1 = gtk.Label("Password: ")
- passlabel1.set_alignment(0, 0.5)
+ passlabel1.set_alignment(1, 0.5)
bottomidentbox.pack_start(passlabel1, False, False, 0)
passlabel1.show()
@@ -268,7 +274,6 @@ class APRSActivity(activity.Activity):
self.latDDtext.set_max_length(2)
self.latDDtext.set_width_chars(4)
self.latDDtext.set_text("DD")
- self.latDDtext.select_region(1,2)
self.latDDtext.connect("changed", self.disable_beacon)
latpositbox.pack_start(self.latDDtext, False, False, 0)
self.latDDtext.show()
@@ -277,7 +282,6 @@ class APRSActivity(activity.Activity):
self.latMMtext.set_max_length(2)
self.latMMtext.set_width_chars(3)
self.latMMtext.set_text("MM")
- self.latMMtext.select_region(1,2)
self.latMMtext.connect("changed", self.disable_beacon)
latpositbox.pack_start(self.latMMtext, False, False, 0)
self.latMMtext.show()
@@ -291,7 +295,6 @@ class APRSActivity(activity.Activity):
self.latmmtext.set_max_length(2)
self.latmmtext.set_width_chars(3)
self.latmmtext.set_text("mm")
- self.latmmtext.select_region(1,2)
self.latmmtext.connect("changed", self.disable_beacon)
latpositbox.pack_start(self.latmmtext, False, False, 0)
self.latmmtext.show()
@@ -316,7 +319,6 @@ class APRSActivity(activity.Activity):
self.lonDDDtext.set_max_length(3)
self.lonDDDtext.set_width_chars(4)
self.lonDDDtext.set_text("DDD")
- self.lonDDDtext.select_region(1,2)
self.lonDDDtext.connect("changed", self.disable_beacon)
lonpositbox.pack_start(self.lonDDDtext, False, False, 0)
self.lonDDDtext.show()
@@ -325,7 +327,6 @@ class APRSActivity(activity.Activity):
self.lonMMtext.set_max_length(2)
self.lonMMtext.set_width_chars(3)
self.lonMMtext.set_text("MM")
- self.lonMMtext.select_region(1,2)
self.lonMMtext.connect("changed", self.disable_beacon)
lonpositbox.pack_start(self.lonMMtext, False, False, 0)
self.lonMMtext.show()
@@ -339,7 +340,6 @@ class APRSActivity(activity.Activity):
self.lonmmtext.set_max_length(2)
self.lonmmtext.set_width_chars(3)
self.lonmmtext.set_text("mm")
- self.lonmmtext.select_region(1,2)
self.lonmmtext.connect("changed", self.disable_beacon)
lonpositbox.pack_start(self.lonmmtext, False, False, 0)
self.lonmmtext.show()
@@ -433,7 +433,7 @@ class APRSActivity(activity.Activity):
self.messageview.set_justification(gtk.JUSTIFY_LEFT)
self.messageview.modify_font(smallfont)
- self.messagebuffer.set_text("Welcome to APRS-XO.\n\nThis program sends your position information to a server that will\nthen display your location on a webpage. This program requires an\nactive Internet connection to work.\n\nSelect an APRS Site\nSelecting a button will copy the URI to the clipboard.\n\nIndentifiers\nEnter your callsign and optionally an aprsd password.\n\nStation Comment\nData in the Station Comment field will appear after your location\ninformation on the website.")
+ self.messagebuffer.set_text("Welcome to APRS-XO.\n\nThis program sends your position information to a server that will\ndisplay your location on a webpage. This program requires an\nactive Internet connection to work.\n\nSelect an APRS Site\nSelecting a button will copy the URI to the clipboard.\n\nIndentifiers\nEnter your callsign and optionally an aprsd password.\n\nStation Comment\nData in the Station Comment field will appear after your location\ninformation on the website.")
self.messagewindow = gtk.ScrolledWindow()
self.messagewindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
@@ -458,7 +458,6 @@ class APRSActivity(activity.Activity):
self.messagecombo.show()
self.messagetext = gtk.Entry()
- # TODO should this be lower with acks?
self.messagetext.set_max_length(67)
self.messagetext.set_width_chars(32)
self.messagetext.modify_font(smallfont)
@@ -512,22 +511,6 @@ class APRSActivity(activity.Activity):
win.pack_start(rightwin, False, False, 0)
rightwin.show()
- # for quick testing
- if (TESTING):
- self.calltext.set_text("kg4gjy")
- self.passtext.set_text("18107")
- self.latDDtext.set_text("35")
- self.latMMtext.set_text("7")
- self.latmmtext.set_text("42")
- self.latcombo.set_active(0)
- self.lonDDDtext.set_text("85")
- self.lonMMtext.set_text("6")
- self.lonmmtext.set_text("93")
- self.loncombo.set_active(0)
-# self.stationtext.set_text("")
- self.ziptext.set_text("")
- self.beaconbutton.set_active(True)
-
win.show()
self.calltext.grab_focus()
@@ -630,31 +613,32 @@ class APRSActivity(activity.Activity):
recv_data = sock.recv(RECV_BUFFER)
except:
self.status_write("Server closed connection.\n")
+ self.sock = None
return False
if not recv_data:
self.status_write("Server closed connection.\n")
+ self.sock = None
return False
else:
- # find uri's http or else www
- webaddy = recv_data.lower().find("http")
- if (webaddy != -1):
- recv_data = ("%s\n%s" % (recv_data[:webaddy], recv_data[webaddy:]))
- else:
- webaddy = recv_data.lower().find("www")
+ # sometimes more than one packet comes in
+ for packet in recv_data.split("\n"):
+ if (len(packet) < 2):
+ break
+ # find uri's http or else www
+ webaddy = packet.lower().find("http")
if (webaddy != -1):
- recv_data = ("%s\n%s" % (recv_data[:webaddy], recv_data[webaddy:]))
- if (recv_data[0] == "#"):
- self.status_write("%s\n\n" % recv_data)
- else:
- cuthere = recv_data.find(":")
- self.status_write("%s\n" % recv_data[:cuthere+1])
-
- # some incoming lines end in \n and some do not
- if (recv_data[-1:] == "\n"):
- self.status_write("%s\n" % recv_data[cuthere+1:])
+ packet = ("%s\n%s" % (packet[:webaddy], packet[webaddy:]))
+ else:
+ webaddy = packet.lower().find("www")
+ if (webaddy != -1):
+ packet = ("%s\n%s" % (packet[:webaddy], packet[webaddy:]))
+ if (packet[0] == "#"):
+ self.status_write("%s\n\n" % packet)
else:
- self.status_write("%s\n\n" % recv_data[cuthere+1:])
- self.msg_check(recv_data)
+ cuthere = packet.find(":")
+ self.status_write("%s\n" % packet[:cuthere+1])
+ self.status_write("%s\n\n" % packet[cuthere+1:])
+ self.msg_check(packet)
return True
def send_beacon(self):
@@ -678,8 +662,14 @@ class APRSActivity(activity.Activity):
self.status_write("%s\n\n" % msg)
return True
- def send_ack(self, msg):
- self.send_data(msg)
+ def send_ack(self, tocall, sequence):
+ # should check for duplicate messages in the next 30 seconds and drop them
+ # aprsd does this for us - but should do it here as well
+ if (tocall in self.sent_acks):
+ currentack = self.sent_acks[tocall]
+ if (currentack == sequence):
+ ackmessage = ":%s:ack%s" % (tocall, sequence)
+ self.send_data(ackmessage)
return False
def status_write(self, text):
@@ -905,92 +895,63 @@ class APRSActivity(activity.Activity):
fromcall = data[:data.find(">")].upper()
isbulletin = self.bulletin_check(strippedtocall)
if (isbulletin):
- message = data[firstcheck+12:-1]
- # TODO add BLN, etc to tocall dropdown list?
-# self.add_callsign(fromcall, False)
- # for now, display them every time
- self.message_write("%s %s.%s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, strippedtocall, message))
+ message = data[firstcheck+12:]
+ self.add_callsign(fromcall, False)
+ bln_id = "%s-%s" % (fromcall, strippedtocall)
+ if (not bln_id in self.seen_bulletins):
+ self.seen_bulletins[bln_id] = 1
+ self.message_write("%s %s:%s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, strippedtocall, message))
else:
if (strippedtocall == self.calltext.get_text()):
self.add_callsign(fromcall, False)
if (thirdcheck != -1):
sequence_end = data.find("}")
if (sequence_end == -1):
- sequence = data[thirdcheck+1:-1]
+ sequence = data[thirdcheck + 1:]
else:
- sequence = data[thirdcheck+1:sequence_end]
- replyack = data[sequence_end+1:-1]
- if (replyack[0:3] == "ack"):
- self.recv_acks["%s-%s" % (fromcall, replyack[3:])] = 1
+ sequence = data[thirdcheck + 1:sequence_end]
+ replyack = data[sequence_end + 1:]
+ if (len(replyack) > 1):
+ ackid = "%s-%s" % (fromcall, replyack)
+ if (ackid in self.recv_acks):
+ if (self.recv_acks[ackid] == 0):
+ count_start = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid])
+ count_end = count_start.forward_search(">", gtk.TEXT_SEARCH_TEXT_ONLY)
+ self.messagebuffer.delete(count_start, count_end[0])
+ self.send_msg_queue(fromcall)
+ self.recv_acks[ackid] = 1
message = data[firstcheck+12:thirdcheck]
- ackmessage = ":%s:ack%s" % (fromcall, sequence)
+# ackmessage = ":%s:ack%s" % (fromcall, sequence)
+ ackmessage = ":%s:ack%s" % (fromcall, data[thirdcheck + 1:])
self.send_data(ackmessage)
id = "%s-%s" % (fromcall, sequence)
if (id in self.sent_acks):
- self.timers.append(gobject.timeout_add(30 * 1000, self.send_ack, ackmessage))
- self.timers.append(gobject.timeout_add(60 * 1000, self.send_ack, ackmessage))
- self.timers.append(gobject.timeout_add(120 * 1000, self.send_ack, ackmessage))
+ self.timers.append(gobject.timeout_add(30 * 1000, self.send_ack, tocall, sequence))
+ self.timers.append(gobject.timeout_add(60 * 1000, self.send_ack, tocall, sequence))
+ self.timers.append(gobject.timeout_add(120 * 1000, self.send_ack, tocall, sequence))
else:
+ # TODO beep?
self.message_write("%s %s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, message))
self.sent_acks[id] = time.time() # to help a cleanup thread later
self.sent_acks[fromcall] = sequence # to help with reply acks later
else:
- message = data[firstcheck+12:-1]
- if (message[0:3] == "ack"):
- self.recv_acks["%s-%s" % (fromcall, message[3:])] = 1
- else:
- self.message_write("%s %s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, message))
-
- def msg_check_old(self, data):
- # a quick "does it look like a message?" check
- # this check will only find messages that require acks
- firstcheck = data.find("::")
- secondcheck = data.find("{")
- # FIX this will ignore BLN, ALL, QST, CQ, etc with { in message
- # FIXME actually a BLN with a { freezes the status window..
- if (firstcheck != -1 and secondcheck != -1):
- # great, it looks kinda like a message, is it to me?
- tocall = data[firstcheck+2:firstcheck+11].upper()
- strippedtocall = tocall.strip()
- if (strippedtocall == self.calltext.get_text()):
- sequence_end = data.find("}")
- if (sequence_end == -1):
- sequence = data[secondcheck+1:-1]
- else:
- sequence = data[secondcheck+1:sequence_end]
- fromcall = data[:data.find(">")].upper()
- message = data[firstcheck+12:secondcheck]
- self.add_callsign(fromcall, False)
- ackmessage = ":%s:ack%s" % (fromcall, sequence)
- self.send_data(ackmessage)
- id = "%s-%s" % (fromcall, sequence)
- if (id in self.sent_acks):
- self.timers.append(gobject.timeout_add(30 * 1000, self.send_ack, ackmessage))
- self.timers.append(gobject.timeout_add(60 * 1000, self.send_ack, ackmessage))
- self.timers.append(gobject.timeout_add(120 * 1000, self.send_ack, ackmessage))
- else:
- self.message_write("%s %s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, message))
-
- self.sent_acks[id] = time.time() # to help a cleanup thread later
- self.sent_acks[fromcall] = sequence # to help with reply acks later
- else:
- # is it a message that does not get acked?
- if (firstcheck != -1):
- tocall = data[firstcheck+2:firstcheck+11].upper()
- strippedtocall = tocall.strip()
- fromcall = data[:data.find(">")].upper()
- message = data[firstcheck+12:-1]
- if (strippedtocall == "ALL" or strippedtocall == "QST" or strippedtocall == "CQ" or strippedtocall[:3] == "BLN" or strippedtocall[:3] == "NWS"):
- # for now, display them every time
- self.message_write("%s %s:%s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, strippedtocall, message))
- else:
- # is it an ack (to me)?
- if (strippedtocall == self.calltext.get_text()):
+ message = data[firstcheck+12:]
if (message[0:3] == "ack"):
- # record the message as acked to stop repeating it
- self.recv_acks["%s-%s" % (fromcall, message[3:])] = 1
+ sequence_end = message.find("}")
+ if (sequence_end == -1):
+ sequence = message[3:]
+ else:
+ sequence = message[3:sequence_end]
+ ackid = "%s-%s" % (fromcall, sequence)
+ if (ackid in self.recv_acks):
+ if (self.recv_acks[ackid] == 0):
+ count_start = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid])
+ count_end = count_start.forward_search(">", gtk.TEXT_SEARCH_TEXT_ONLY)
+ self.messagebuffer.delete(count_start, count_end[0])
+ self.send_msg_queue(fromcall)
+ self.recv_acks[ackid] = 1
else:
- # no ack and addressed to me.
+ # TODO beep?
self.message_write("%s %s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), fromcall, message))
def disable_beacon(self, widget, data=None):
@@ -1014,9 +975,14 @@ class APRSActivity(activity.Activity):
return True
def send_message(self, widget, data=None):
+ sendnow = False
+
tocall = self.messagedest.get_text().upper()
message = self.messagetext.get_text()
+ if (message == ""):
+ return False
+
isbulletin = self.bulletin_check(tocall)
# check for illegal characters before clearing message
@@ -1029,8 +995,6 @@ class APRSActivity(activity.Activity):
self.message_write("Messages can not contain the following characters: | ~ {")
return False
- self.messagetext.set_text("")
-
# add callsign to list if just entered
if (self.messagecombo.get_active() == -1):
self.add_callsign(tocall, True)
@@ -1043,27 +1007,23 @@ class APRSActivity(activity.Activity):
sequence = "%s" % self.b90()
# TODO
- # check to see if there is an unack-ed message to same callsign
- # too many to the same call? give an error instead
- # too many in general? give an error instead
- # print message + QUEUED add to the queue...
# cancel message option - menu popup
- # TODO save location for repeat/ack counter, queued and cancelled locations too
- # put the message in the message window
-# self.message_write("%s %s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), self.calltext.get_text(), message))
- self.message_write("%s To:%s> %s\n" % (time.strftime("%m/%d %H:%M", time.localtime()), tocall, message))
+ # is there a queue for this callsign?
+ if (tocall not in self.queue_list):
+ sendnow = True
- # send the message
- if (isbulletin):
- self.send_data(":%s:%s" % (tocall.ljust(9), message))
- # TODO what are the correct timings for bulletins?
- gobject.timeout_add(600 * 1000, self.msg_timer, tocall, message, "", 2, 600)
- else:
- replyack = self.replyack(tocall)
- self.send_data(":%s:%s{%s}%s" % (tocall.ljust(9), message, sequence, replyack))
- self.recv_acks["%s-%s" % (tocall, sequence)] = 0
- gobject.timeout_add(7 * 1000, self.msg_timer, tocall, message, sequence, 2, 7)
+ # add the message to the queue
+ if (not self.msg_queue(tocall, sequence, message)):
+ if (self.sequence > 0):
+ self.sequence -= 1
+ return False
+
+ # clear the message text box
+ self.messagetext.set_text("")
+
+ if (sendnow):
+ self.send_msg_queue(tocall)
def b90(self):
if (self.sequence > 8099):
@@ -1075,15 +1035,35 @@ class APRSActivity(activity.Activity):
return output
def msg_timer(self, tocall, message, sequence, count, delay):
- if (self.recv_acks["%s-%s" % (tocall, sequence)] == 1):
+ id = "%s-%s" % (tocall, sequence)
+ if (self.recv_acks[id] == 1):
return False
else:
replyack = self.replyack(tocall)
self.send_data(":%s:%s{%s}%s" % (tocall.ljust(9), message, sequence, replyack))
+ count_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ count_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ count_end.forward_chars(len(str(count - 1)) + 1)
+ self.messagebuffer.delete(count_start, count_end)
+ iter = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ self.messagebuffer.insert(iter, " %i" % count)
+
# start the next timer
count += 1
if (count > MAXRETRIES):
+ self.recv_acks[id] = 1
+
+ count_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ count_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ count_end.forward_chars(len(str(count - 1)) + len(str(MAXRETRIES)) + 2)
+ self.messagebuffer.delete(count_start, count_end)
+
+ line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ line_end.forward_to_line_end()
+ self.messagebuffer.insert(line_end, " * TIMEOUT *")
+
+ self.send_msg_queue(tocall)
return False
delay *= 2
if (delay > 600):
@@ -1122,7 +1102,7 @@ class APRSActivity(activity.Activity):
def bulletin_check(self, callsign):
for currentcall in self.bulletins:
length = len(currentcall)
- if (currentcall == callsign[0:length]):
+ if (currentcall == callsign[:length]):
return True
return False
@@ -1132,5 +1112,60 @@ class APRSActivity(activity.Activity):
id = "%s-%s" % (tocall, self.sent_acks[tocall])
if (time.time() - self.sent_acks[id] < 5400):
# less than 90 minutes ago
- replyack = "ack%s" % self.sent_acks[tocall]
+ replyack = self.sent_acks[tocall]
return replyack
+
+ def msg_queue(self, call, sequence, message):
+ if (len(self.message_list) >= MAX_MSG_QUEUE):
+ self.message_write("Too many messages in queue.\n")
+ return False
+ id = "%s-%s" % (call, sequence)
+ if (call in self.queue_list):
+ if (len(self.queue_list[call]) >= MAX_PER_CALL_QUEUE):
+ self.message_write("Too many messages to %s in queue.\n" % call)
+ return False
+ self.queue_list[call].append(sequence)
+ self.message_list[id] = message
+ else:
+ self.queue_list[call] = []
+ self.queue_list[call].append(sequence)
+ self.message_list[id] = message
+ self.message_write("%s To:%s> %s * QUEUED *\n" % (time.strftime("%m/%d %H:%M", time.localtime()), call, message))
+ # if a message is received before the next lines are run there will be problems...
+ iter = self.messagebuffer.get_iter_at_line(self.messagebuffer.get_line_count() - 2)
+ iter.forward_chars(15 + len(call))
+ self.message_marks[id] = self.messagebuffer.create_mark(None, iter, True)
+# self.message_marks[id].set_visible(True)
+ return True
+
+ def send_msg_queue(self, call):
+ if (call in self.queue_list):
+ if (self.queue_list[call] == []):
+ del self.queue_list[call]
+ return False
+ sequence = self.queue_list[call].pop(0)
+ id = "%s-%s" % (call, sequence)
+ message = self.message_list[id]
+ del self.message_list[id]
+
+ # send message
+ isbulletin = self.bulletin_check(call)
+ if (isbulletin):
+ self.send_data(":%s:%s" % (call.ljust(9), message))
+ # TODO what are the correct timings for bulletins?
+ gobject.timeout_add(600 * 1000, self.msg_timer, call, message, "", 2, 600)
+ else:
+ replyack = self.replyack(call)
+ self.send_data(":%s:%s{%s}%s" % (call.ljust(9), message, sequence, replyack))
+ self.recv_acks["%s-%s" % (call, sequence)] = 0
+ gobject.timeout_add(7 * 1000, self.msg_timer, call, message, sequence, 2, 7)
+
+ # clear "QUEUED" and add the counter
+ line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ queue_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ line_end.forward_to_line_end()
+ queue_start.forward_to_line_end()
+ queue_start.backward_chars(11)
+ self.messagebuffer.delete(queue_start, line_end)
+ iter = self.messagebuffer.get_iter_at_mark(self.message_marks[id])
+ self.messagebuffer.insert(iter, " 1/%s" % MAXRETRIES)