"""
LodgeIt!
~~~~~~~~
A script that pastes stuff into the enzotools pastebin on
paste.enzotools.org.
Modified (very, very slightly) from the original script by the authors
below.
.lodgeitrc / _lodgeitrc
-----------------------
Under UNIX create a file called ``~/.lodgeitrc``, under Windows
create a file ``%APPDATA%/_lodgeitrc`` to override defaults::
language=default_language
clipboard=true/false
open_browser=true/false
encoding=fallback_charset
:authors: 2007-2008 Georg Brandl <georg@python.org>,
2006 Armin Ronacher <armin.ronacher@active-4.com>,
2006 Matt Good <matt@matt-good.net>,
2005 Raphael Slinckx <raphael@slinckx.net>
"""
import os
import sys
from optparse import OptionParser
SCRIPT_NAME = os.path.basename(sys.argv[0])
VERSION = "0.3"
SERVICE_URL = "http://paste.yt-project.org/"
SETTING_KEYS = ["author", "title", "language", "private", "clipboard", "open_browser"]
# global server proxy
_xmlrpc_service = None
[docs]
def fail(msg, code):
"""Bail out with an error message."""
print(f"ERROR: {msg}", file=sys.stderr)
sys.exit(code)
[docs]
def load_default_settings():
"""Load the defaults from the lodgeitrc file."""
settings = {
"language": None,
"clipboard": True,
"open_browser": False,
"encoding": "iso-8859-15",
}
rcfile = None
if os.name == "posix":
rcfile = os.path.expanduser("~/.lodgeitrc")
elif os.name == "nt" and "APPDATA" in os.environ:
rcfile = os.path.expandvars(r"$APPDATA\_lodgeitrc")
if rcfile:
try:
f = open(rcfile)
for line in f:
if line.strip()[:1] in "#;":
continue
p = line.split("=", 1)
if len(p) == 2:
key = p[0].strip().lower()
if key in settings:
if key in ("clipboard", "open_browser"):
settings[key] = p[1].strip().lower() in (
"true",
"1",
"on",
"yes",
)
else:
settings[key] = p[1].strip()
f.close()
except OSError:
pass
settings["tags"] = []
settings["title"] = None
return settings
[docs]
def make_utf8(text, encoding):
"""Convert a text to UTF-8, brute-force."""
try:
u = str(text, "utf-8")
uenc = "utf-8"
except UnicodeError:
try:
u = str(text, encoding)
uenc = "utf-8"
except UnicodeError:
u = str(text, "iso-8859-15", "ignore")
uenc = "iso-8859-15"
try:
import chardet
except ImportError:
return u.encode("utf-8")
d = chardet.detect(text)
if d["encoding"] == uenc:
return u.encode("utf-8")
return str(text, d["encoding"], "ignore").encode("utf-8")
[docs]
def get_xmlrpc_service():
"""Create the XMLRPC server proxy and cache it."""
global _xmlrpc_service
import xmlrpc.client
if _xmlrpc_service is None:
try:
_xmlrpc_service = xmlrpc.client.ServerProxy(
SERVICE_URL + "xmlrpc/", allow_none=True
)
except Exception as err:
fail(f"Could not connect to Pastebin: {err}", -1)
return _xmlrpc_service
[docs]
def copy_url(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 PIPE, Popen
try:
client = Popen(["pbcopy"], stdin=PIPE)
except OSError:
try:
import pygtk
pygtk.require("2.0")
import gobject
import gtk
except ImportError:
return
gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD).set_text(url)
gobject.idle_add(gtk.main_quit)
gtk.main()
else:
client.stdin.write(url)
client.stdin.close()
client.wait()
else:
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(url)
win32clipboard.CloseClipboard()
[docs]
def open_webbrowser(url):
"""Open a new browser window."""
import webbrowser
webbrowser.open(url)
[docs]
def language_exists(language):
"""Check if a language alias exists."""
xmlrpc = get_xmlrpc_service()
langs = xmlrpc.pastes.getLanguages()
return language in langs
[docs]
def get_mimetype(data, filename):
"""Try to get MIME type from data."""
try:
import gnomevfs
except ImportError:
from mimetypes import guess_type
if filename:
return guess_type(filename)[0]
else:
if filename:
return gnomevfs.get_mime_type(os.path.abspath(filename))
return gnomevfs.get_mime_type_for_data(data)
[docs]
def print_languages():
"""Print a list of all supported languages, with description."""
xmlrpc = get_xmlrpc_service()
languages = xmlrpc.pastes.getLanguages().items()
def cmp(x, y):
# emulate Python2's builtin cmp function
# https://docs.python.org/2.7/library/functions.html#cmp
# https://docs.python.org/3/whatsnew/3.0.html#ordering-comparisons
return (x > y) - (x < y)
languages.sort(lambda a, b: cmp(a[1].lower(), b[1].lower()))
print("Supported Languages:")
for alias, name in languages:
print(f" {alias:<30}{name}")
[docs]
def download_paste(uid):
"""Download a paste given by ID."""
xmlrpc = get_xmlrpc_service()
paste = xmlrpc.pastes.getPaste(uid)
if not paste:
fail(f'Paste "{uid}" does not exist.', 5)
code = paste["code"]
print(code)
[docs]
def create_paste(code, language, filename, mimetype, private):
"""Create a new paste."""
xmlrpc = get_xmlrpc_service()
rv = xmlrpc.pastes.newPaste(language, code, None, filename, mimetype, private)
if not rv:
fail("Could not create paste. Something went wrong on the server side.", 4)
return rv
[docs]
def compile_paste(filenames, langopt):
"""Create a single paste out of zero, one or multiple files."""
def read_file(f):
try:
return f.read()
finally:
f.close()
mime = ""
lang = langopt or ""
if not filenames:
data = read_file(sys.stdin)
if not langopt:
mime = get_mimetype(data, "") or ""
fname = ""
elif len(filenames) == 1:
fname = filenames[0]
data = read_file(open(filenames[0], "rb"))
if not langopt:
mime = get_mimetype(data, filenames[0]) or ""
else:
result = []
for fname in filenames:
data = read_file(open(fname, "rb"))
if langopt:
result.append(f"### {fname} [{langopt}]\n\n")
else:
result.append(f"### {fname}\n\n")
result.append(data)
result.append("\n\n")
data = "".join(result)
lang = "multi"
return data, lang, fname, mime
[docs]
def main(
filename,
languages=False,
language=None,
encoding="utf-8",
open_browser=False,
private=False,
clipboard=False,
download=None,
):
"""Paste a given script into a pastebin using the Lodgeit tool."""
# usage = ('Usage: %%prog [options] [FILE ...]\n\n'
# 'Read the files and paste their contents to %s.\n'
# 'If no file is given, read from standard input.\n'
# 'If multiple files are given, they are put into a single paste.'
# % SERVICE_URL)
# parser = OptionParser(usage=usage)
#
# settings = load_default_settings()
#
# parser.add_option('-v', '--version', action='store_true',
# help='Print script version')
# parser.add_option('-L', '--languages', action='store_true', default=False,
# help='Retrieve a list of supported languages')
# parser.add_option('-l', '--language', default=settings['language'],
# help='Used syntax highlighter for the file')
# parser.add_option('-e', '--encoding', default=settings['encoding'],
# help='Specify the encoding of a file (default is '
# 'utf-8 or guessing if available)')
# parser.add_option('-b', '--open-browser', dest='open_browser',
# action='store_true',
# default=settings['open_browser'],
# help='Open the paste in a web browser')
# parser.add_option('-p', '--private', action='store_true', default=False,
# help='Paste as private')
# parser.add_option('--no-clipboard', dest='clipboard',
# action='store_false',
# default=settings['clipboard'],
# help="Don't copy the url into the clipboard")
# parser.add_option('--download', metavar='UID',
# help='Download a given paste')
#
# opts, args = parser.parse_args()
#
if languages:
print_languages()
return
elif download:
download_paste(download)
return
# check language if given
if language and not language_exists(language):
print(f"Language {language} is not supported.")
return
# load file(s)
args = [filename]
try:
data, language, filename, mimetype = compile_paste(args, language)
except Exception as err:
fail(f"Error while reading the file(s): {err}", 2)
if not data:
fail("Aborted, no content to paste.", 4)
# create paste
code = make_utf8(data, encoding).decode("utf-8")
pid = create_paste(code, language, filename, mimetype, private)
url = f"{SERVICE_URL}show/{pid}/"
print(url)
if open_browser:
open_webbrowser(url)
if clipboard:
copy_url(url)