Modified parse() to handle multiple updates on same line. Added gensig.py script.
diff --git a/infocalypse/fms.py b/infocalypse/fms.py --- a/infocalypse/fms.py +++ b/infocalypse/fms.py @@ -52,7 +52,6 @@ def send_msgs(fms_host, fms_port, msg_tu #print raw_msg try: server.post(in_file) - pass finally: in_file.close() finally: @@ -120,7 +119,8 @@ def clean_nym(fms_id): return fms_id[pos + 1:] -def to_msg_string(updates, announcements=None): +def to_msg_string(updates, announcements=None, + separator='\n'): """ Dump updates and announcements in a format which can be read by parse. """ if updates is None: @@ -135,21 +135,43 @@ def to_msg_string(updates, announcements announcements = list(announcements) announcements.sort() - text = '' + # Hmmm... extra loops for assert paranoia. for value in announcements: assert is_usk_file(value) - text += "A:%s\n" % value for update in updates: assert is_hex_string(update[0], 12) assert update[1] >= 0 - text += "U:%s:%i\n" % (update[0], update[1]) - return text + tmp = [separator.join(["A:%s" % value for value in announcements]), + separator.join(["U:%s:%i" % (update[0], update[1]) + for update in updates])] + while '' in tmp: + tmp.remove('') + + return separator.join(tmp) + +def parse_updates(fields, updates): + """ Helper function parses updates. """ + if fields[0] != 'U' or len(fields) < 3: + return False + + while len(fields) > 0 and fields[0] == 'U' and len(fields) >= 3: + try: + if is_hex_string(fields[1]): + updates.add((fields[1], int(fields[2]))) + fields = fields[3:] + else: + break + except ValueError: + break + # Doesn't imply success, just that we tried. + return True # A grepper, not a parser... def parse(text, is_lines=False): """ Parse updates and announcements from raw text. """ + if is_lines: lines = text else: @@ -161,13 +183,10 @@ def parse(text, is_lines=False): for line in lines: line = line.strip() # Handle crlf bs on Windoze. fields = line.split(':') - if fields[0] == 'U' and len(fields) >= 3: - try: - if is_hex_string(fields[1]): - updates.add((fields[1], int(fields[2]))) - except ValueError: - continue - elif fields[0] == 'A' and len(fields) >= 2: + if parse_updates(fields, updates): + continue + + if fields[0] == 'A' and len(fields) >= 2: try: if is_usk_file(fields[1]): announcements.add(fields[1]) @@ -413,12 +432,19 @@ def smoke_test(): # Not values0 because of implicit update. assert values1 == values2 - msg = make_update_msg('djk@isFiaD04zgAgnrEC5XJt1i4IE7AkNPqhBG5bONi6Yks' - 'test', - 'test', - values0[0], - values0[1]) - send_msgs('127.0.0.1', 11119, (msg, )) + # Test sig style update strings. + text = to_msg_string(values0[0], None, ':') + print text + values3 = parse(text) + assert values3 == (values0[0], ()) + + # msg = make_update_msg('djk@isFiaD04zgAgnrEC5XJt1i4IE7AkNPqhBG5bONi6Yks' + # 'infocalypse.tst', + # 'infocalypse.tst', + # values0[0], + # values0[1]) + # DOH! This goes over the wire + #send_msgs('127.0.0.1', 11119, (msg, )) if __name__ == "__main__": smoke_test() diff --git a/infocalypse/gensig.py b/infocalypse/gensig.py new file mode 100755 --- /dev/null +++ b/infocalypse/gensig.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +# Need to suppress all exceptions. +# pylint: disable-msg=W0702 + +""" Program to print an fms/freemail signature string with embedded + repo update information. + + Copyright (C) 2009 Darrell Karbott + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2.0 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Author: djk@isFiaD04zgAgnrEC5XJt1i4IE7AkNPqhBG5bONi6Yks + + This program has no command line interface. + You must modify the variables at the top of the file. +""" +import os + +from fcpclient import get_usk_hash +from config import Config, DEFAULT_CFG_PATH +from fms import to_msg_string + +# The maximum number of updates to include. +MAX_UPDATES = 4 # == 67 chars + +# The full path to your .infocalypse / infocalypse.ini +# file. Should work for the default location. +CFG_PATH = os.path.expanduser(DEFAULT_CFG_PATH) + +# The static part of your sig message with no trailing '\n' +STATIC_TEXT = ('Incremental hg repos in Freenet (Not pyfreenethg!):\n' + + 'USK@-bk9znYylSCOEDuSWAvo5m72nUeMxKkDmH3nIqAeI-0,' + + 'qfu5H3FZsZ-5rfNBY-jQHS5Ke7AT2PtJWd13IrPZjcg,' + + 'AQACAAE/feral_codewright/8/source.html') + +# Your repo Request (not Insert!) URIs go here: +# +# The versions don't matter, they are read from your .infocalpse file. +# Hmmm... using repo uris means you can broadcast information about +# repos you have pulled but didn't insert. +REPO_USKS = ('USK@kRM~jJVREwnN2qnA8R0Vt8HmpfRzBZ0j4rHC2cQ-0hw,' + + '2xcoQVdQLyqfTpF2DpkdUIbHFCeL4W~2X1phUYymnhM,' + + 'AQACAAE/fred_staging.R1/1', + 'USK@kRM~jJVREwnN2qnA8R0Vt8HmpfRzBZ0j4rHC2cQ-0hw,' + + '2xcoQVdQLyqfTpF2DpkdUIbHFCeL4W~2X1phUYymnhM,' + + 'AQACAAE/infocalypse.hgext.R1/12', + ) + +USK_HASHES = tuple([get_usk_hash(usk) for usk in REPO_USKS]) + +def print_updates(): + """ Print a sig message with embedded update strings or nothing + at all if there's an error. """ + try: + stored_cfg = Config.from_file(CFG_PATH) + updates = [] + for usk_hash in USK_HASHES: + index = stored_cfg.get_index(usk_hash) + if index is None: + # Uncomment this and run from the command line if + # you get no output. + #print "No stored index for usk hash: ", usk_hash + continue + updates.append((usk_hash, index)) + updates.sort() + # Hmmm... silently truncate + updates = updates[:MAX_UPDATES] + if len(updates) > 0: + print STATIC_TEXT + print to_msg_string(updates, None, ':') + except: + # Fail silently, rather than spewing garbage into sig. + return + +if __name__ == "__main__": + print_updates()