Source

hgpaste / hgpaste.py

# -*- coding: utf-8 -*-
"""
    hgpaste
    ~~~~~~~

    Mercurial extension to quickly paste a diff to a LodgeIt instance.

    Usage: activate the extension and set the name of your server in hgrc::

        [extensions]
        hgpaste = path/to/hgpaste.py

        [paste]
        server = http://paste.pocoo.org/

    Then, use "hg paste [FILES]" to paste the current changes to FILES in the
    working dir, or "hg paste -r REV" to paste an export of the specified
    revision.

    :copyright: 2009 by Georg Brandl.
    :license:
        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 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.,
        51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
import sys

from mercurial import commands, cmdutil, patch

def copy_to_clipboard(url):
    """Copy the url into the clipboard."""
    # try windows first
    try:
        import win32clipboard
    except ImportError:
        # then give pbcopy a try.  do that before gtk because
        # gtk might be installed on os x but nobody is interested
        # in the X11 clipboard there.
        from subprocess import Popen, PIPE
        for prog in 'pbcopy', 'xclip':
            try:
                client = Popen([prog], stdin=PIPE)
            except OSError:
                continue
            else:
                client.stdin.write(url)
                client.stdin.close()
                client.wait()
                break
        else:
            # keep gtk's import magic from fail
            from mercurial import demandimport
            demandimport.ignore.append('gobject._gobject')
            try:
                import pygtk
                pygtk.require('2.0')
                import gtk
                import gobject
            except ImportError:
                return
            gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD).set_text(url)
            gobject.idle_add(gtk.main_quit)
            gtk.main()
    else:
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardText(url)
        win32clipboard.CloseClipboard()

def paste(ui, repo, *pats, **opts):
    """Paste current working directory changes or a specified changeset.

    When -r REV is not given, treat the remaining arguments as for the
    "hg diff" command and paste the resulting diff.  When -r REV is
    given, export the revision and paste that.

    The paste is done on http://paste.pocoo.org/ by default, but a
    different server with a compatible XMLRPC interface can be selected
    in the configuration (add a "server" value in a "paste" section).

    By default, the pasted text is also copied to the system clipboard;
    the -n option prevents that.
    """
    import xmlrpclib
    server = ui.config('paste', 'server', 'http://paste.pocoo.org/')
    if not server.endswith('/'):
        server += '/'
    proxy = xmlrpclib.ServerProxy(server + 'xmlrpc/', allow_none=True)

    ui.pushbuffer()
    if opts['rev']:
        revs = cmdutil.revrange(repo, opts.pop('rev'))
        try:
            export = cmdutil.export
        except AttributeError:
            export = patch.export
        export(repo, revs, fp=ui, opts=patch.diffopts(ui, opts))
    else:
        commands.diff(ui, repo, *pats, **opts)
    content = ui.popbuffer()
    if not content:
        ui.warn('Error: nothing to paste.\n')
        return

    rv = proxy.pastes.newPaste('diff', content, None, '', '', False)
    if not rv:
        ui.warn('Could not create paste; server returned failure.\n')
    else:
        url = '%sshow/%s/' % (server, rv)
        ui.status(url + '\n')
        if not opts['nocopy']:
            copy_to_clipboard(url)

cmdtable = {
    'paste':
        (paste,
         [('r', 'rev', [], 'paste specified revision(s)'),
          ('n', 'nocopy', None, 'do not copy to clipboard')] + commands.diffopts,
         'hg paste [-r REV | FILE...]')
}