Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
## hgemail.py - TortoiseHg's dialog for sending patches via email## Copyright (C) 2007 Steve Borho <steve@borho.org># Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>#importosimportsysimportgobjectimportgtkimportpangoimportshlibfromtempfileimportmkstempfromdialogimport*frommercurialimporthg,ui,extensionsfrommercurial.i18nimport_fromhglibimportRepoError,fromutf,toutffromthgconfigimportConfigDialogfromhgcmdimportCmdDialogclassEmailDialog(gtk.Window):""" Send patches or bundles via email """def__init__(self,root='',revargs=[]):""" Initialize the Dialog """gtk.Window.__init__(self,gtk.WINDOW_TOPLEVEL)shlib.set_tortoise_icon(self,'hg.ico')self.root=rootself.revargs=revargsself.tbar=gtk.Toolbar()self.tips=gtk.Tooltips()tbuttons=[self._toolbutton(gtk.STOCK_GOTO_LAST,_('send'),self._on_send_clicked,_('Send email(s)')),self._toolbutton(gtk.STOCK_FIND,_('test'),self._on_test_clicked,_('Show email(s) which would be sent')),gtk.SeparatorToolItem(),self._toolbutton(gtk.STOCK_PREFERENCES,_('configure'),self._on_conf_clicked,_('Configure email settings'))]forbtnintbuttons:self.tbar.insert(btn,-1)mainvbox=gtk.VBox()self.add(mainvbox)mainvbox.pack_start(self.tbar,False,False,2)# set dialog titleifrevargs[0]in('--outgoing','-o'):self.set_title(_('Email outgoing changes'))elifrevargs[0]in('--rev','-r'):self.set_title(_('Email revision(s) ')+' '.join(revargs[1:]))else:self.set_title(_('Email Mercurial Patches'))self.set_default_size(630,400)hbox=gtk.HBox()envframe=gtk.Frame(_('Envelope'))flagframe=gtk.Frame(_('Options'))hbox.pack_start(envframe,True,True,4)hbox.pack_start(flagframe,False,False,4)mainvbox.pack_start(hbox,False,True,4)vbox=gtk.VBox()envframe.add(vbox)# To: combo boxhbox=gtk.HBox()self._tolist=gtk.ListStore(str)self._tobox=gtk.ComboBoxEntry(self._tolist,0)lbl=gtk.Label(_('To:'))lbl.set_property('width-chars',5)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._tobox,True,True,4)vbox.pack_start(hbox,False,False,4)# Cc: combo boxhbox=gtk.HBox()self._cclist=gtk.ListStore(str)self._ccbox=gtk.ComboBoxEntry(self._cclist,0)lbl=gtk.Label(_('Cc:'))lbl.set_property('width-chars',5)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._ccbox,True,True,4)vbox.pack_start(hbox,False,False,4)# From: combo boxhbox=gtk.HBox()self._fromlist=gtk.ListStore(str)self._frombox=gtk.ComboBoxEntry(self._fromlist,0)lbl=gtk.Label(_('From:'))lbl.set_property('width-chars',5)lbl.set_alignment(1.0,0.5)hbox.pack_start(lbl,False,False,4)hbox.pack_start(self._frombox,True,True,4)vbox.pack_start(hbox,False,False,4)vbox=gtk.VBox()flagframe.add(vbox)self.tooltips=gtk.Tooltips()self._normal=gtk.RadioButton(None,_('Send changesets as HG patches'))vbox.pack_start(self._normal,True,True,4)self.tooltips.set_tip(self._normal,_('HG patches (as generated by export command) are compatible'' with most patch programs. They include a header which'' contains the most important changeset metadata.'))self._git=gtk.RadioButton(self._normal,_('Use extended (git) patch format'))vbox.pack_start(self._git,True,True,4)self.tooltips.set_tip(self._git,_('Git patches can describe binary files, copies, and'' permission changes, but recipients may not be able to'' use them if they are not using git or Mercurial.'))self._plain=gtk.RadioButton(self._normal,_('Plain, do not prepend HG header'))vbox.pack_start(self._plain,True,True,4)self.tooltips.set_tip(self._plain,_('Stripping Mercurial header removes username and parent'' information. Only useful if recipient is not using'' Mercurial (and does not like to see the headers).'))self._bundle=gtk.RadioButton(self._normal,_('Send single binary bundle, not patches'))vbox.pack_start(self._bundle,True,True,4)self.tooltips.set_tip(self._bundle,_('Bundles store complete changesets in binary form.' ' Upstream users can pull from them. This is the safest'
' way to send changes to recipient Mercurial users.'))
+ hbox = gtk.HBox()+ vbox.pack_start(hbox, False, False, 2)++ self._attach = gtk.CheckButton(_('attach'))+ self.tooltips.set_tip(self._attach, + _('send patches as attachments'))+ self._inline = gtk.CheckButton(_('inline'))+ self.tooltips.set_tip(self._inline, + _('send patches as inline attachments'))+ self._diffstat = gtk.CheckButton(_('diffstat'))+ self.tooltips.set_tip(self._diffstat, + _('add diffstat output to messages'))+ hbox.pack_start(self._attach, True, True, 2)+ hbox.pack_start(self._inline, True, True, 2)+ hbox.pack_start(self._diffstat, True, True, 2)+ vbox = gtk.VBox()
hbox = gtk.HBox()
self._subjlist = gtk.ListStore(str)
self._subjbox=gtk.ComboBoxEntry(self._subjlist,0)hbox.pack_start(gtk.Label(_('Subject:')),False,False,4)hbox.pack_start(self._subjbox,True,True,4)vbox.pack_start(hbox,False,False,4)self.descview=gtk.TextView(buffer=None)self.descview.set_editable(True)self.descview.modify_font(pango.FontDescription('Monospace'))self.descbuffer=self.descview.get_buffer()scrolledwindow=gtk.ScrolledWindow()scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)scrolledwindow.add(self.descview)frame=gtk.Frame(_('Patch Series (Bundle) Description'))frame.set_border_width(4)vbox.pack_start(scrolledwindow,True,True,4)vbox.set_border_width(4)eventbox=gtk.EventBox()eventbox.add(vbox)frame.add(eventbox)self._eventbox=eventboxmainvbox.pack_start(frame,True,True,4)gobject.idle_add(self._refresh,True)def_toolbutton(self,stock,label,handler,tip):tbutton=gtk.ToolButton(stock)tbutton.set_label(label)tbutton.set_tooltip(self.tips,tip)tbutton.connect('clicked',handler)returntbuttondef_refresh(self,initial):deffill_history(history,vlist,cpath):vlist.clear()ifcpathnotinhistory.get_keys():returnforvinhistory.get_value(cpath):vlist.append([v])history=shlib.Settings('config_history')try:repo=hg.repository(ui.ui(),path=self.root)self.repo=repoexceptRepoError:self.repo=Nonereturnextensions.load(self.repo.ui,'patchbomb',None)ifinitial:# Only zap these fields at startupself._tobox.child.set_text(fromutf(repo.ui.config('email','to','')))self._ccbox.child.set_text(fromutf(repo.ui.config('email','cc','')))self._frombox.child.set_text(fromutf(repo.ui.config('email','from','')))self._subjbox.child.set_text(fromutf(repo.ui.config('email','subject','')))self._intro=Falseforarginextensions.find('patchbomb').cmdtable['email'][1]:ifarg[1]=='intro':self._intro=Truebreakifself._intro:addtip=''else:addtip=' '+_('The description field is unused ''when sending a single patch.')self.tooltips.set_tip(self._eventbox,_('Patch series description is sent in initial summary'' email with [PATCH 0 of N] subject. It should describe'' the effects of the entire patch series. When emailing'' a bundle, these fields make up the message subject and body.')+addtip)fill_history(history,self._tolist,'email.to')fill_history(history,self._cclist,'email.cc')fill_history(history,self._fromlist,'email.from')fill_history(history,self._subjlist,'email.subject')# See if user has set flags in defaults.email self._git.set_sensitive(True)
self._bundle.set_sensitive(True)
self._plain.set_sensitive(True)
+ self._inline.set_sensitive(True)+ self._attach.set_sensitive(True)+ self._diffstat.set_sensitive(True) defaults = repo.ui.config('defaults', 'email', '').split()
for flag in defaults:
if flag in ('-g', '--git'):
self._git.set_active(True)self._git.set_sensitive(False)ifflagin('-b','--bundle'):self._bundle.set_active(True)self._bundle.set_sensitive(False) if flag in ('--plain'):
self._plain.set_active(True)
self._plain.set_sensitive(False)
+ if flag in ('i', '--inline'):+ self._inline.set_active(True)+ self._inline.set_sensitive(False)+ if flag in ('a', '--attach'):+ self._attach.set_active(True)+ self._attach.set_sensitive(False)+ if flag in ('d', '--diffstat'):+ self._diffstat.set_active(True)+ self._diffstat.set_sensitive(False) def _on_conf_clicked(self, button):
dlg = ConfigDialog(self.root, False)
dlg.show_all()dlg.focus_field('email.from')dlg.run()dlg.hide()self._refresh(False)def_on_send_clicked(self,button):self.send()def_on_test_clicked(self,button):self.send(True)defsend(self,test=False):defrecord_new_value(cpath,history,newvalue):ifnotnewvalue:returnifcpathnotinhistory.get_keys():history.set_value(cpath,[])elifnewvalueinhistory.get_value(cpath):history.get_value(cpath).remove(newvalue)history.get_value(cpath).insert(0,newvalue)totext=fromutf(self._tobox.child.get_text())cctext=fromutf(self._ccbox.child.get_text())fromtext=fromutf(self._frombox.child.get_text())subjtext=fromutf(self._subjbox.child.get_text())ifnottotext:info_dialog(self,_('Info required'),_('You must specify a recipient'))self._tobox.grab_focus()returnifnotfromtext:info_dialog(self,_('Info required'),_('You must specify a sender address'))self._frombox.grab_focus()returnifnotself.repo:returnifself.repo.ui.config('email','method','smtp')=='smtp'andnottest:ifnotself.repo.ui.config('smtp','host'):info_dialog(self,_('Info required'),_('You must configure SMTP'))dlg=ConfigDialog(self.root,False)dlg.show_all()dlg.focus_field('smtp.host')dlg.run()dlg.hide()self._refresh(False)returnifnottest:history=shlib.Settings('config_history')record_new_value('email.to',history,totext)record_new_value('email.cc',history,cctext)record_new_value('email.from',history,fromtext)record_new_value('email.subject',history,subjtext)history.write()cmdline=['hg','email','-f',fromtext,'-t',totext,'-c',cctext]cmdline+=['--repository',self.repo.root]iftest:cmdline.insert(2,'--test')ifsubjtext:cmdline+=['--subject',subjtext]ifself._intro:cmdline+=['--intro']ifself._bundle.get_active():cmdline+=['--bundle']if'--outgoing'inself.revargs: self.revargs.remove('--outgoing')
elif self._plain.get_active(): cmdline += ['--plain']
elif self._git.get_active(): cmdline += ['--git']
+ if self._inline.get_active(): cmdline += ['--inline']+ if self._attach.get_active(): cmdline += ['--attach']+ if self._diffstat.get_active(): cmdline += ['--diffstat'] start = self.descbuffer.get_start_iter()
end = self.descbuffer.get_end_iter()
desc = self.descbuffer.get_text(start, end)
try:fd,tmpfile=mkstemp(prefix="thg_emaildesc_")os.write(fd,desc)os.close(fd)cmdline+=['--desc',tmpfile]cmdline.extend(self.revargs)dlg=CmdDialog(cmdline)dlg.show_all()dlg.run()dlg.hide()finally:os.unlink(tmpfile)defrun(root='',**opts):# In most use cases, this dialog will be launched by other# hggtk tools like glog and synch. It's not expected to be# used from hgtk. I leave this path in place for testing purposes.dialog=EmailDialog(root,['tip'])dialog.show_all()dialog.connect('destroy',gtk.main_quit)gtk.gdk.threads_init()gtk.gdk.threads_enter()gtk.main()gtk.gdk.threads_leave()if__name__=="__main__":opts={}opts['root']=len(sys.argv)>1andsys.argv[1]oros.getcwd()run(**opts)
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.