First pass at implementation of fn-fmsnotify --submit This bundles all locally committed changes that aren't in the repo in Freenet and inserts the bundle on a CHK. Then it sends a machine readable patch notification to the fmsnotify_group set in the .infocalypse / infocalypse.ini file.
diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py --- a/infocalypse/__init__.py +++ b/infocalypse/__init__.py @@ -571,6 +571,7 @@ def infocalypse_fmsnotify(ui_, repo, **o return params['ANNOUNCE'] = opts['announce'] + params['SUBMIT'] = opts['submit'] params['DRYRUN'] = opts['dryrun'] params['INSERT_URI'] = insert_uri execute_fmsnotify(ui_, repo, params, stored_cfg) @@ -724,7 +725,9 @@ cmdtable = { "fn-fmsnotify": (infocalypse_fmsnotify, [('', 'dryrun', None, "don't send fms message"), - ('', 'announce', None, "include full URI update"), ] + ('', 'announce', None, "include full URI update"), + ('', 'submit', None, "insert patch bundle and send an " + + "fms notification"),] + FCP_OPTS, # Needs to invert the insert uri "[options]"), diff --git a/infocalypse/fmscmds.py b/infocalypse/fmscmds.py --- a/infocalypse/fmscmds.py +++ b/infocalypse/fmscmds.py @@ -29,7 +29,7 @@ from fms import recv_msgs, to_msg_string USKNotificationParser, show_table from config import Config, trust_id_for_repo, untrust_id_for_repo, known_hashes -from infcmds import do_key_setup, setup, cleanup +from infcmds import do_key_setup, setup, cleanup, execute_insert_patch def handled_list(ui_, params, stored_cfg): """ INTERNAL: HACKED""" @@ -198,7 +198,7 @@ def execute_fmsnotify(ui_, repo, params, usk_hash = get_usk_hash(request_uri) index = stored_cfg.get_index(usk_hash) - if index is None: + if index is None and not params['SUBMIT']: ui_.warn("Can't notify because there's no stored index " + "for %s.\n" % usk_hash) return @@ -215,12 +215,16 @@ def execute_fmsnotify(ui_, repo, params, ui_.status("Update the fmsnotify_group = line and try again.\n") return + subject = 'Update:' + '/'.join(request_uri.split('/')[1:]) if params['ANNOUNCE']: text = to_msg_string(None, (request_uri, )) + elif params['SUBMIT']: + params['REQUEST_URI'] = request_uri # REDFLAG: DCI. Think + text = execute_insert_patch(ui_, repo, params, stored_cfg) + subject = 'Patch:' + '/'.join(request_uri.split('/')[1:]) else: text = to_msg_string(((usk_hash, index), )) - subject = 'Update:' + '/'.join(request_uri.split('/')[1:]) msg_tuple = (stored_cfg.defaults['FMS_ID'], stored_cfg.defaults['FMSNOTIFY_GROUP'], subject, diff --git a/infocalypse/infcmds.py b/infocalypse/infcmds.py --- a/infocalypse/infcmds.py +++ b/infocalypse/infcmds.py @@ -19,14 +19,12 @@ Author: djk@isFiaD04zgAgnrEC5XJt1i4IE7AkNPqhBG5bONi6Yks """ - # REDFLAG: cleanup exception handling # by converting socket.error to IOError in fcpconnection? # REDFLAG: returning vs aborting. set system exit code. import os import socket import time - from binascii import hexlify from mercurial import util @@ -633,13 +631,6 @@ def execute_reinsert(ui_, repo, params, finally: cleanup(update_sm) - -# REDFLAG: move into fcpclient? -#def usks_equal(usk_a, usk_b): -# assert is_usk(usk_a) and and is_usk(usk_b) -# return (get_usk_for_usk_version(usk_a, 0) == -# get_usk_for_usk_version(usk_b, 0)) - def execute_push(ui_, repo, params, stored_cfg): """ Run the push command. """ @@ -947,23 +938,17 @@ def create_patch_bundle(ui_, repo, freen finally: ui_.popbuffer() - - # explicitly specify heads? - - # insert it into freenet as a CHK - -# ':', '|' not in freenet base64 -def patch_msg(usk_hash, bases, heads, chk, kind='B'): - """ Return a machine readable patch notification suitable for posting - via FMS. """ - return ':'.join((kind, usk_hash, ':'.join([base[:12] for base in bases]), - '|', ':'.join([head[:12] for head in heads]), chk)) def execute_insert_patch(ui_, repo, params, stored_cfg): """ Create and hg bundle containing all changes not already in the - infocalypse repo in Freenet and insert it to a CHK. """ + infocalypse repo in Freenet and insert it to a CHK. + + Returns a machine readable patch notification message. + """ try: update_sm = setup(ui_, repo, params, stored_cfg) out_file = make_temp_file(update_sm.ctx.bundle_cache.base_dir) + + ui_.status("Reading repo state from Freenet...\n") freenet_heads = read_freenet_heads(params, update_sm, params['REQUEST_URI']) @@ -980,6 +965,11 @@ def execute_insert_patch(ui_, repo, para request.in_params.file_name = out_file request.in_params.send_data = True + # Must do this here because file gets deleted. + chk_len = os.path.getsize(out_file) + + ui_.status("Inserting %i byte patch bundle...\n" % + os.path.getsize(out_file)) update_sm.start_single_request(request) run_until_quiescent(update_sm, params['POLL_SECS']) @@ -987,19 +977,22 @@ def execute_insert_patch(ui_, repo, para freenet_heads.sort() heads = [hexlify(head) for head in repo.heads()] heads.sort() - if update_sm.get_state(QUIESCENT).arrived_from(((FINISHING,))): chk = update_sm.get_state(RUNNING_SINGLE_REQUEST).\ final_msg[1]['URI'] ui_.status("Patch CHK:\n%s\n" % chk) + # ':', '|' not in freenet base64 + ret = ':'.join(('B', normalize(params['REQUEST_URI']), str(chk_len), + ':'.join([base[:12] for base in freenet_heads]), + '|', ':'.join([head[:12] for head in heads]), chk)) - ui_.status("\nNotification:\n%s\n" % - patch_msg(normalize(params['REQUEST_URI']), - freenet_heads, heads, chk) + '\n') + ui_.status("\nNotification:\n%s\n" % ret + + '\n') + return ret - else: - ui_.status("Insert failed.\n") + raise util.Abort("Patch CHK insert failed.") + finally: # Cleans up out file. cleanup(update_sm)