diff --git a/UTILITIES/pw b/UTILITIES/pw index 890c72b82..2821ef638 100755 --- a/UTILITIES/pw +++ b/UTILITIES/pw @@ -29,13 +29,22 @@ import subprocess import base64 import ConfigParser import datetime +import smtplib +import urllib import re +from email.mime.text import MIMEText + +notify_on_state_change = { + 'Accepted': 'emacs-orgmode@gnu.org', + 'RFC': 'emacs-orgmode@gnu.org' +} + # Default Patchwork remote XML-RPC server URL # This script will check the PW_XMLRPC_URL environment variable # for the URL to access. If that is unspecified, it will fallback to # the hardcoded default value specified here. -DEFAULT_URL = "http://patchwork/xmlrpc/" +DEFAULT_URL = "http://patchwork.newartisans.com/xmlrpc/" CONFIG_FILES = [os.path.expanduser('~/.pwclientrc')] class Filter: @@ -267,7 +276,8 @@ def action_apply(rpc, patch_id): sys.stderr.write("Error: No patch content found\n") sys.exit(1) -def action_update_patch(rpc, patch_id, state = None, commit = None): +def action_update_patch(rpc, patch_id, state = None, commit = None, + delegate_str = "", archived = False): patch = rpc.patch_get(patch_id) if patch == {}: sys.stderr.write("Error getting information on patch ID %d\n" % \ @@ -276,6 +286,16 @@ def action_update_patch(rpc, patch_id, state = None, commit = None): params = {} + delegate_id = None + if delegate_str != "": + params['delegate'] = delegate_str + ids = person_ids_by_name(rpc, delegate_str) + if len(ids) == 0: + sys.stderr.write("Note: Nobody found matching *%s*\n", \ + delegate_str) + else: + delegate_id = ids[0] + if state: state_id = state_id_by_name(rpc, state) if state_id == 0: @@ -283,11 +303,55 @@ def action_update_patch(rpc, patch_id, state = None, commit = None): sys.exit(1) params['state'] = state_id + if state in notify_on_state_change: + if not delegate_id: + sys.stderr.write("Error: Delete (-d) required for this update\n") + sys.exit(1) + + person = rpc.person_get(delegate_id) + submitter = rpc.person_get(patch['submitter_id']) + + from_addr = '%s <%s>' % (person['name'], person['email']) + cc_addr = '%s <%s>' % (submitter['name'], submitter['email']) + to_addr = notify_on_state_change[state] + + longdesc = '''Patch %s (http://patchwork.newartisans.com/patch/%s/) is now %s. + +This relates to the following submission: + +http://mid.gmane.org/%s''' % \ + (patch['id'], patch['id'], state, urllib.quote(patch['msgid'])) + shortdesc = 'Patch %s %s' % (patch['id'], state) + + msg = MIMEText(longdesc) + + msg['Subject'] = 'Patchwork: ' + shortdesc + msg['From'] = from_addr + msg['To'] = to_addr + #msg['Cc'] = cc_addr + msg['References'] = patch['msgid'] + + # Send the message via our own SMTP server, but don't include + # the envelope header. + try: + s = smtplib.SMTP('localhost') + print "Sending e-mail to: %s, %s" % (to_addr, cc_addr) + s.sendmail(from_addr, [to_addr, cc_addr], msg.as_string()) + s.quit() + except: + sys.stderr.write("Warning: Failed to send e-mail " + + "(no SMTP server listening at localhost?)\n") + if commit: params['commit_ref'] = commit + if archived: + params['archived'] = archived + success = False try: + print "Updating patch %d to state '%s', delegate %s" % \ + (patch_id, state, delegate_str) success = rpc.patch_set(patch_id, params) except xmlrpclib.Fault, f: sys.stderr.write("Error updating patch: %s\n" % f.faultString) @@ -308,7 +372,7 @@ def patch_id_from_hash(rpc, project, hash): return patch['id'] -def branch_with(patch_id, rpc): +def branch_with(patch_id, rpc, delegate_str): s = rpc.patch_get_mbox(patch_id) if len(s) > 0: print unicode(s).encode("utf-8") @@ -356,12 +420,45 @@ def branch_with(patch_id, rpc): os.waitpid(proc.pid, 0) return + # If it succeeded this far, mark the patch as "Under Review" by the + # invoking user. + action_update_patch(rpc, patch_id, state = 'Under Review', + delegate_str = delegate_str) + proc = subprocess.Popen(['git', 'rebase', 'master']) sts = os.waitpid(proc.pid, 0) print sha -auth_actions = ['update'] +def merge_with(patch_id, rpc, delegate_str): + s = rpc.patch_get_mbox(patch_id) + if len(s) > 0: + print unicode(s).encode("utf-8") + + proc = subprocess.Popen(['git', 'checkout', 'master']) + sts = os.waitpid(proc.pid, 0) + if sts[1] != 0: + sys.stderr.write("Failed to checkout master branch\n") + return + + proc = subprocess.Popen(['git', 'merge', '--ff', 't/patch%s' % patch_id]) + sts = os.waitpid(proc.pid, 0) + if sts[1] != 0: + sys.stderr.write("Failed to merge t/patch%s into master\n" % patch_id) + return + + proc = subprocess.Popen(['git', 'rev-parse', 'master'], + stdout = subprocess.PIPE) + sha = proc.stdout.read()[:-1] + + # If it succeeded this far, mark the patch as "Accepted" by the invoking + # user. + action_update_patch(rpc, patch_id, state = 'Accepted', commit = sha, + delegate_str = delegate_str, archived = True) + + print sha + +auth_actions = ['update', 'branch', 'merge'] def main(): try: @@ -478,7 +575,16 @@ def main(): sys.stderr.write("Invalid patch ID given\n") sys.exit(1) - branch_with(patch_id, rpc) + branch_with(patch_id, rpc, config.get('auth', 'username')) + + elif action == 'merge': + try: + patch_id = patch_id or int(args[0]) + except: + sys.stderr.write("Invalid patch ID given\n") + sys.exit(1) + + merge_with(patch_id, rpc, config.get('auth', 'username')) elif action == 'view': try: @@ -517,7 +623,7 @@ def main(): sys.exit(1) action_update_patch(rpc, patch_id, state = state_str, - commit = commit_str) + commit = commit_str, delegate_str = delegate_str) else: sys.stderr.write("Unknown action '%s'\n" % action) diff --git a/doc/org.texi b/doc/org.texi index b4e1999ed..a9511eecb 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -12292,32 +12292,54 @@ with the cursor at the beginning of a headline. @section Code evaluation and security issues Org files can contain embedded code snippets in many programming languages. +<<<<<<< HEAD Org provides tool to work with the code snippets, including evaluating them. +======= +Org mode provides tool ti work with hte code snippets, and that includes +evaluation. +>>>>>>> new-pw Running code on your machine always comes with a security risk. Badly written or malicious code can be executed on purpose or by accident. Org has default settings which will only evaluate such code if you give explicit +<<<<<<< HEAD permission to do so, and as a casual user of these features you should leave +======= +permission to do so, and as a casual user of these features you should levae +>>>>>>> new-pw these precautions intact. For people who regularly work with such code, the confirmation prompts can become annoying, and you might want to turn them off. This can be done, but you must be aware of the risks that are involved. +<<<<<<< HEAD Code evaluation can happen under the following circumstances: +======= +Code evaluation can happen under the following circumstances +>>>>>>> new-pw @table @i @item Source code blocks Source code blocks can be evaluated during export, or when pressing @kbd{C-c +<<<<<<< HEAD C-c} in the block. The most important thing to realize here is that Org mode files which contain code snippets are in a certain sense like executable files. So you should accept them and load them into Emacs only from trusted sources - just like you would do with a program you install on your computer. +======= +C-c} in the block. @b{Security advice:} The most important thing to realize +here is that Org mode files which contain code snippets are in a certain +sense like executable files. So you should accept them and load them into +Emacs only from trusted sources - just like you would do with a program you +install on your computer. +>>>>>>> new-pw Make sure you know what you are doing before customizing the variables which take of the default security brakes. @defopt org-confirm-babel-evaluate +<<<<<<< HEAD Does code evaluation have to be acknowledged by the user? @end defopt @@ -12332,10 +12354,27 @@ Function to queries user about shell link execution. @defopt org-confirm-elisp-link-function Functions to query user for Emacs Lisp link execution. @end defopt +======= +????????????????????? +@end defopt + +@defopt org-not-evluation-with-C-c-C-c + +@item Following @code{shell} and @code{elisp} links +Org has two link types that can directly evaluate code (@pxref{External +links}). These links can be problematic because the code to be evaluated his +not visible. @b{Security advice:} Do not use these links, use source code +blocks which make the associated actions much more transparent. +>>>>>>> new-pw @item Formulas in tables Formulas in tables (@pxref{The spreadsheet}) are code that is evaluated either by the @i{calc} interpreter, or by the @i{Emacs Lisp} interpreter. +<<<<<<< HEAD +======= +@b{Security advice:} If you get a file from an untrusted source, do not +update tables without looking at complex formulas. +>>>>>>> new-pw @end table