def thanks_record_pr(lmsg): datadir = b4.get_data_dir() # Check if we're tracking it already filename = '%s.pr' % lmsg.pr_remote_tip_commit for entry in os.listdir(datadir): if entry == filename: return allto = utils.getaddresses([str(x) for x in lmsg.msg.get_all('to', [])]) allcc = utils.getaddresses([str(x) for x in lmsg.msg.get_all('cc', [])]) out = { 'msgid': lmsg.msgid, 'subject': lmsg.full_subject, 'fromname': lmsg.fromname, 'fromemail': lmsg.fromemail, 'to': b4.format_addrs(allto), 'cc': b4.format_addrs(allcc), 'references': b4.LoreMessage.clean_header(lmsg.msg['References']), 'remote': lmsg.pr_repo, 'ref': lmsg.pr_ref, 'sentdate': b4.LoreMessage.clean_header(lmsg.msg['Date']), 'quote': b4.make_quote(lmsg.body, maxlines=6) } fullpath = os.path.join(datadir, filename) with open(fullpath, 'w', encoding='utf-8') as fh: json.dump(out, fh, ensure_ascii=False, indent=4) logger.debug('Wrote %s for thanks tracking', filename)
def send_messages(listing, gitdir, outdir, branch, since='1.week'): # Not really sending, but writing them out to be sent on your own # We'll probably gain ability to send these once the feature is # more mature and we're less likely to mess things up datadir = b4.get_data_dir() logger.info('Generating %s thank-you letters', len(listing)) # Check if the outdir exists and if it has any .thanks files in it if not os.path.exists(outdir): os.mkdir(outdir) usercfg = b4.get_user_config() # Do we have a .signature file? sigfile = os.path.join(str(Path.home()), '.signature') if os.path.exists(sigfile): with open(sigfile, 'r', encoding='utf-8') as fh: signature = fh.read() else: signature = '%s <%s>' % (usercfg['name'], usercfg['email']) outgoing = 0 for jsondata in listing: slug_from = re.sub(r'\W', '_', jsondata['fromemail']) slug_subj = re.sub(r'\W', '_', jsondata['subject']) slug = '%s_%s' % (slug_from.lower(), slug_subj.lower()) slug = re.sub(r'_+', '_', slug) jsondata['myname'] = usercfg['name'] jsondata['myemail'] = usercfg['email'] jsondata['signature'] = signature if 'pr_commit_id' in jsondata: # This is a pull request msg = generate_pr_thanks(gitdir, jsondata, branch) else: # This is a patch series msg = generate_am_thanks(gitdir, jsondata, branch, since) if msg is None: continue outgoing += 1 outfile = os.path.join(outdir, '%s.thanks' % slug) logger.info(' Writing: %s', outfile) msg.set_charset('utf-8') msg.replace_header('Content-Transfer-Encoding', '8bit') with open(outfile, 'w') as fh: fh.write(msg.as_string(policy=b4.emlpolicy)) logger.debug('Cleaning up: %s', jsondata['trackfile']) fullpath = os.path.join(datadir, jsondata['trackfile']) os.rename(fullpath, '%s.sent' % fullpath) logger.info('---') if not outgoing: logger.info('No thanks necessary.') return logger.debug('Wrote %s thank-you letters', outgoing) logger.info('You can now run:') logger.info(' git send-email %s/*.thanks', outdir)
def thanks_record_am(lser, cherrypick=None): if not lser.complete: logger.debug('Incomplete series, not tracking for thanks') return # Are we tracking this already? datadir = b4.get_data_dir() slug = lser.get_slug(extended=True) filename = '%s.am' % slug patches = list() at = 0 for pmsg in lser.patches[1:]: at += 1 if pmsg is None: continue if cherrypick is not None and at not in cherrypick: logger.debug('Skipped non-cherrypicked: %s', at) continue pmsg.load_hashes() if pmsg.attestation is None: logger.debug( 'Unable to get hashes for all patches, not tracking for thanks' ) return patches.append((pmsg.subject, pmsg.pwhash, pmsg.msgid)) lmsg = lser.patches[0] if lmsg is None: lmsg = lser.patches[1] allto = email.utils.getaddresses( [str(x) for x in lmsg.msg.get_all('to', [])]) allcc = email.utils.getaddresses( [str(x) for x in lmsg.msg.get_all('cc', [])]) out = { 'msgid': lmsg.msgid, 'subject': lmsg.full_subject, 'fromname': lmsg.fromname, 'fromemail': lmsg.fromemail, 'to': b4.format_addrs(allto), 'cc': b4.format_addrs(allcc), 'references': b4.LoreMessage.clean_header(lmsg.msg['References']), 'sentdate': b4.LoreMessage.clean_header(lmsg.msg['Date']), 'quote': b4.make_quote(lmsg.body, maxlines=5), 'patches': patches, } fullpath = os.path.join(datadir, filename) with open(fullpath, 'w', encoding='utf-8') as fh: json.dump(out, fh, ensure_ascii=False, indent=4) logger.debug('Wrote %s for thanks tracking', filename)
def list_tracked(): # find all tracked bits tracked = list() datadir = b4.get_data_dir() paths = sorted(Path(datadir).iterdir(), key=os.path.getmtime) for fullpath in paths: if fullpath.suffix not in ('.pr', '.am'): continue with fullpath.open('r', encoding='utf-8') as fh: jsondata = json.load(fh) jsondata['trackfile'] = fullpath.name if fullpath.suffix == '.pr': jsondata['pr_commit_id'] = fullpath.stem tracked.append(jsondata) return tracked
def discard_selected(cmdargs): tracked = list_tracked() if not len(tracked): logger.info('Nothing to do') sys.exit(0) if cmdargs.discard == 'all': listing = tracked else: listing = list() for num in b4.parse_int_range(cmdargs.discard, upper=len(tracked)): try: index = int(num) - 1 listing.append(tracked[index]) except ValueError: logger.critical('Please provide the number of the message') logger.info('---') write_tracked(tracked) sys.exit(1) except IndexError: logger.critical('Invalid index: %s', num) logger.info('---') write_tracked(tracked) sys.exit(1) if not len(listing): logger.info('Nothing to do') sys.exit(0) datadir = b4.get_data_dir() logger.info('Discarding %s messages', len(listing)) for jsondata in listing: fullpath = os.path.join(datadir, jsondata['trackfile']) os.rename(fullpath, '%s.discarded' % fullpath) logger.info(' Discarded: %s', jsondata['subject']) sys.exit(0)