#!/usr/bin/env python## pastebin, a script to upload a file to pastebin.ca from the console.## Copyright (C) 2005 Raphael Slinckx <raphael@slinckx.net># Thanks to Gustavo J. A. M. Carneiro <gjc@gnome.org>## 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 getopt, sys, urllib, urllib2, re, pwd, ostry: import gnomevfs, gtksourceview WITH_GNOMEVFS = Trueexcept ImportError: WITH_GNOMEVFS = Falseclass PasteBin: # General Constants _expirations = [ '', '5 minutes', '10 minutes', '15 minutes', '30 minutes', '45 minutes', '1 hour', '2 hours', '4 hours', '8 hours', '12 hours', '1 day', '2 days', '3 days', '1 week', '2 weeks', '3 weeks', '1 month', '2 months', '3 months', '4 months', '5 months', '6 months', '1 year' ] _types = [ 'raw', 'asterisk', 'c', 'cpp', 'php', 'perl', 'java', 'vb', 'csharp', 'ruby', 'python', 'pascal', 'mirc', 'pli', 'xml', 'sql', 'scheme', 'ascript', 'ada', 'apache', 'nasm', 'asp', 'bash', 'css', 'delphi', 'html', 'js', 'lisp', 'lua', 'asm', 'objc', 'vbnet' ] _postdata = 'content=%(content)s&description=%(description)s&type=%(type)s&expiry=%(expiry)s&name=%(name)s&save=0&s=Submit+Post' _posturl = 'http://en.pastebin.ca/index.php' _baseurl = 'http://en.pastebin.ca' _name_type_dict = { 'HTML' : 'html', 'CSS' : 'css', 'JavaScript': 'js', 'sh' : 'bash', 'Python': 'python', 'PHP' : 'php', 'Perl' : 'perl', 'SQL': 'sql', 'C' : 'c', 'Ada' : 'ada', 'Lua' : 'lua', 'C++': 'cpp', 'Pascal': 'pascal', 'C#' : 'csharp', 'XML' : 'xml', 'VB.NET': 'vbnet', 'Java': 'java', 'Ruby' : 'ruby' } def is_type(selfclass, type): return type in selfclass._types is_type = classmethod(is_type) def get_type_from_mimetype(selfclass, name): return selfclass._name_type_dict[name] get_type_from_mimetype = classmethod(get_type_from_mimetype) def unique(x): if sys.version_info < (2, 3, 0, 'final', 0): raise RuntimeError('Python 2.3 or later is required.') elif sys.version_info < (2, 4, 0, 'final', 0): from sets import Set return list(Set(x)) else: return list(set(x)) unique = staticmethod(unique) def __init__(self, name=None, expiry='', type='raw', rawmode=False): if name is None: name = pwd.getpwuid(os.getuid())[0] # user login name self.name = name if expiry not in self._expirations: raise ValueError('Unknown expiration "%s".' % expiry) self.expiry = expiry if type not in self._types: raise ValueError('Unknown type "%s".' % type) self.type = type if rawmode not in [False, True]: raise ValueError('Unknown raw mode indicator "%s".' % rawmode) self.rawmode = rawmode def new_request(self, content, description): payload = self._postdata % { 'content' : urllib.quote_plus(content), 'description' : urllib.quote_plus(description), 'type' : self._types.index(self.type)+1, 'expiry' : urllib.quote_plus(self.expiry), 'name' : urllib.quote_plus(self.name) } req = urllib2.Request(self._posturl, payload, { 'Referer': '%s/' % self._baseurl, 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050813 Epiphany/1.7.6', 'Accept-Language': 'en', 'Accept-Charset': 'utf-8', }) return req def paste(self, content, description): res = None urls = [] try: req = self.new_request(content, description) res = urllib2.urlopen(req).read() except Exception, msg: self.handle_error(msg) else: urls.extend(self.parse_response(res)) if not urls: self.handle_error('Could not retreive pastebin url from page.') return self.unique(urls) def handle_error(self, err): sys.stderr.write('%r\n' % err) def parse_response(self, res): url_pattern = re.compile('%s/\d+' % self._baseurl) for match in url_pattern.findall(res): if self.rawmode: yield match.replace('pastebin.ca/','pastebin.ca/raw/') else: yield match raise StopIterationdef usage(): print """=== Pastebin: Usage$ pastebin [OPTIONS] [FILE]Print the pastebin.ca URL of the input fileIf FILE is omitted content is read from standard inputOPTIONS: -h, --help Print this help notice. -r, --raw Retreive raw text URL (default=off). -d, --description The description of the content (default=empty). -m, --message Same as description -n, --name Your name (default=your unix username). -l, --lines The line numbers to send starting at 1 (default=1,0) Ex: 1,12 or 12,36 or 45 or 45,0 -t, --type The type of the content (default="raw") Type can be one of: raw, asterisk, c, cpp, php, perl, java, vb, csharp, ruby, python, pascal, mirc, pli, xml, sql, scheme, ascript, ada, apache, nasm, asp, bash, css, delphi, html, js, lisp, lua, asm, objc, vbnet If type is not specified, an attempt to auto-detect type is made, based on file data/extension. Detection is more reliable when giving FILE argument than piping directly. This needs modules gnomevfs and gtksourceview"""if __name__ == '__main__': if WITH_GNOMEVFS: man = gtksourceview.SourceLanguagesManager() else: man = None # Default Values content = '' description = '' name = None expiry = '' type = 'raw' rawmode = False start = 1 end = 0 try: opts, args = getopt.getopt(sys.argv[1:], 'hrd:m:n:t:l:', ['help', 'raw', 'description=', 'message=', 'name=', 'type=', 'lines=']) except getopt.GetoptError: usage() sys.exit() for o, a in opts: if o in ('-h', '--help'): usage() sys.exit() if o in ('-l', '--lines'): #Parse the line numbers try: lines = a.split(',') if len(lines) == 2: if lines[0] != '' and lines[1] != '': start = int(lines[0]) end = int(lines[1]) elif lines[0] == '' and lines[1] != '': start = 1 end = int(lines[1]) elif lines[0] != '' and lines[1] == '': start = int(lines[0]) end = 0 elif len(lines) == 1: start = int(lines[0]) except Exception: start = 1 end = 0 if start > end and end != 0 or start < 1 or end < 0: sys.stderr.write('Error with lines numbers, start:%d end:%d\n' % (start, end)) sys.exit() # Open the file, and read content. f = None try: if len(args) == 0: f = sys.stdin else: f = file(args[0], 'r') lines = None if end == 0: lines = f.readlines()[start-1:] else: lines = f.readlines()[start-1:end] content = ''.join(lines) f.close() except Exception, msg: sys.stderr.write('Error while reading the file: %s\n' % msg) sys.exit() # Try to guess file content type if given, and we have GNOMEVFS if WITH_GNOMEVFS: mimes = [gnomevfs.get_mime_type_for_data(content)] if len(args) > 0: try: mimes.append(gnomevfs.get_mime_type(os.path.abspath(args[0]))) except RuntimeError: sys.stderr.write('Could not determine mime type of "%s".\n' % args[0]) for mime in mimes: lang = man.get_language_from_mime_type(mime) if lang != None: name = lang.get_name() try: type = PasteBin.get_type_from_mimetype(name) sys.stderr.write('Using source type "%s"\n' % type) except KeyError: sys.stderr.write('No pastebin langage matching name "%s"\n' % name) # Parse options for o, a in opts: if o in ('-r', '--raw'): rawmode = True elif o in ('-d', '--description') or o in ('-m', '--message'): description = a elif o in ('-n', '--name'): name = a elif o in ('-t', '--type'): type = a #Parameter validation if content.strip() == '': sys.stderr.write('Content Empty: "%s"\n' % content) sys.exit() elif not PasteBin.is_type(type): sys.stderr.write('Unknown type: %s\n' % type) sys.exit() pb = PasteBin(name, expiry, type, rawmode) print '\n'.join(pb.paste(content, description))