All pastes #1567525 Raw Edit

alessio

public python v1 · immutable
#1567525 ·published 2009-09-15 21:28 UTC
rendered paste body
#!/usr/bin/env python# -*- coding: utf-8 -*-# nautilus-pastebin - Nautilus extension to paste a file to a pastebin service# Written by:#    Alessio Treglia <quadrispro@ubuntu.com># Copyright (C) 2009, Alessio Treglia## Part of this code has been taken from pastebinit script# pastebinit was written by: #    Stéphane Graber <stgraber@stgraber.org>#    Daniel Bartlett <dan@f-box.org>#    David Paleino <d.paleino@gmail.com># URL: http://www.stgraber.org/download/projects/pastebin/# Copyright (C) 2006-2009, Stéphane Graber, Daniel Bartlett, David Paleino# Distributed under the terms of the GNU GPL-2 license## This package 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 package 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 package; if not, write to the Free Software# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA#import urllibimport gtkimport nautilusimport pynotifyimport os, sys, re, sys, mimetypesimport gettextfrom ConfigParser import ConfigParsergettext.install("nautilus-pastebin")# GlobalsNAME_APP = "nautilus-pastebin"CONFIG_FILENAME = 'nautilus-pastebin.conf'USERCONFIG_RELPATH = '.config/nautilus-pastebin'PATH_APP = '/usr/share/nautilus-pastebin'LOGGING = Trueclass ConfigFileException(Exception):    passpynotify.init("Nautilus pastebin extension")def getConfigurationFilename():    homedir = os.environ.get('HOME')    file_conf = ''    try:        file_conf = os.path.join(homedir, USERCONFIG_RELPATH, CONFIG_FILENAME)        os.stat(file_conf)    except:        file_conf = os.path.join('/etc', CONFIG_FILENAME)    return file_confdef getPluginsPath():    homedir = os.environ.get('HOME')    plugins_dirs = []    tmp = os.path.join(homedir, USERCONFIG_RELPATH)    if os.path.isdir(tmp):        plugins_dirs.append(tmp)    tmp = os.path.join(PATH_APP, 'plugins')    if os.path.isdir(tmp):        plugins_dirs.append(tmp)    return plugins_dirsdef log(message):    if LOGGING:        if sys.version.split()[0] < '3':            print message        else:            print (message)# Custom urlopener to handle 401'sclass pasteURLopener(urllib.FancyURLopener):    def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):            return Noneclass ConfigurationValidator(object):    """Configuration wrapper """    NEEDED_OPTS = ['pastebin']        def validate(self):        log (_("Validating configuration file..."))        conf = {}        opts = self.__config.options('generals')        # Each needed field must be fill'd.        if not set(ConfigurationValidator.NEEDED_OPTS).issubset(set(opts)):            raise ConfigFileException, _("Missing some required values in the configuration file.")        for k in opts:        	conf[k] = self.__config.get('generals', k)        	if k in ConfigurationValidator.NEEDED_OPTS and conf[k] == '':        	    raise ConfigFileException, _("Missing some required values in the configuration file.")        # Everything seems well-configured        for k,v in conf.items():            setattr(self,k,v)        return True            def getPastebinConfiguration(self):        """Retrieve and returns the configuration related to the pastebin service."""        pastebinConfiguration = None        if self.__config.has_section(self.pastebin):            pastebinConfiguration = PastebinConfiguration(                dict(self.__config.items(self.pastebin)) )        return pastebinConfiguration        def reloadConfiguration(self):        """Reload the configuration file"""        log (_("Reloading configuration..."))        self.__config.read(self.filename)    def __init__(self, filename='nautilus-pastebin.conf'):        log (_("Initializing global configuration validator..."))        self.filename = filename        self.__config = ConfigParser()        self.__config.read(filename)class PastebinConfiguration(object):    PARAMETERS = ["website",        "content",        "user",        "jabberid",        "version",        "format",        "parentpid",        "permatag",        "title",        "username",        "password"]    def __init__(self, optionsDict):        log (_("Initializing pastebin configuration..."))        # Initialize all parameters        for k in PastebinConfiguration.PARAMETERS:            setattr(self,k,'')        # Read the configuration and set the parameters        for k,v in optionsDict.items():            setattr(self,k,v)        # Initializing formatMap...        formatMap = dict(map(lambda k: (k,''),            filter(lambda x: x.startswith('text'), mimetypes.types_map.values())))        for i in formatMap.keys(): # Set 'text' as default format            formatMap[i] = 'text'        # Read the custom types list from the configuration        exec(optionsDict['mimetypes'])        self.mimetypes = formatMap    def setFormatByMimeType(self, mimetype):        try:            self.format = self.mimetypes[mimetype]        except KeyError:            return False # unsupported mimetype        return True        def __str__(self):        s = 'Configuration:\n'        for k in PastebinConfiguration.PARAMETERS:            s += "%(k)s = %(v)s\n" % {'k' : k, 'v': getattr(self, k)}        s += "mimetypes = %s" % self.mimetypes.__str__()        return sclass PastebinValidatorFactory(object):    """Singleton factory which returns a validator object dinamically."""    __instance = None    class __impl(object):        """Implementation of the class' methods"""        def getValidator(self, pastebinConfiguration):            website = pastebinConfiguration.website            log (_("Looking for a validator: %s") %website)            if (re.search("http://((([a-zA-Z0-9\-_\.]*)(pastebin\.com)))", website) and not website == "http://www.pastebin.com") or website == "http://pastebin.mozilla.org":                return PastebinComValidator(pastebinConfiguration)            elif re.search("http://((([a-zA-Z0-9\-_\.]*)(pastebin\.ca)))", website):                return PastebinCaValidator(pastebinConfiguration)            elif website == "http://rafb.net":                return RafbNetValidator(pastebinConfiguration)            elif website == "http://stikked.com":                return StikkedComValidator(pastebinConfiguration)            elif website == "http://slexy.org":                return SlexyOrgValidator(pastebinConfiguration)            elif website == "http://fpaste.org":                return FpasteValidator(pastebinConfiguration)            elif website == "http://paste2.org":                return Paste2OrgValidator(pastebinConfiguration)            elif re.search("http://((([a-zA-Z0-9\-_\.]*)(pastey\.net)))", website):                    return PasteyNetValidator(pastebinConfiguration)            elif website == "http://yourpaste.net":                return YourpasteNetValidator(pastebinConfiguration)            elif website == "http://gist.github.com":                return GistGithubComValidator(pastebinConfiguration)            elif website == "http://paste.ubuntu.com":                return PasteUbuntuComValidator(pastebinConfiguration)            elif website == "http://paste.debian.net":                return PasteDebianNetValidator(pastebinConfiguration)            else:                return None # Service has not been recognized    def __init__(self):        if PastebinValidatorFactory.__instance is None:            PastebinValidatorFactory.__instance = PastebinValidatorFactory.__impl()        self.__dict__['_PastebinValidatorFactory__instance'] = PastebinValidatorFactory.__instance    def __getattr__(self, attr):        return getattr(self.__instance, attr)    def __setattr__(self, attr, value):        return setattr(self.__instance, attr, value)class GenericPastebinValidator(object):    NOT_EMPTY_FIELDS = ['website',        'content']    def __init__(self, pastebinConfiguration):        if not self.__class__.__name__ == 'GenericPastebinValidator':            self.conf = pastebinConfiguration        else:            raise NotImplementedError    def validate(self):        if not self.__class__.__name__ == 'GenericPastebinValidator':            if not self.checkNotEmpty(['content', 'website']):                return False            if self.conf.user == '':                self.conf.user = os.environ.get('USER')            return True        else:            raise NotImplementedError    def checkNotEmpty(self, opts):        if not self.__class__.__name__ == 'GenericPastebinValidator':            try:                for i in GenericPastebinValidator.NOT_EMPTY_FIELDS:                    if getattr(self.conf, i) == '':                        raise Exception            except:                return False            return True        else:            raise NotImplementedError    def getParameters(self): raise NotImplementedErrorclass PasteUbuntuComValidator(GenericPastebinValidator):    def validate(self):        PasteUbuntuComValidator.NOT_EMPTY_FIELDS.append('format')        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['poster'] = self.conf.user        params['syntax'] = self.conf.format        params['content'] = self.conf.content        return paramsclass PasteDebianNetValidator(GenericPastebinValidator):    def validate(self):        PasteDebianNetValidator.NOT_EMPTY_FIELDS.append('format')        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['poster'] = self.conf.user        params['lang'] = self.conf.format # "-1" The format, for syntax hilighting, default to plain text        #params['syntax'] = self.conf.format #The format, for syntax hilighting        params['code'] = self.conf.content        params['remember'] = "0" #Do you want a cookie ?        params['expire'] = "259200" # expire in 72h        return paramsclass GistGithubComValidator(GenericPastebinValidator):    def validate(self):        GistGithubComValidator.NOT_EMPTY_FIELDS.extend(['format', 'title'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['page'] = "/gists"        params['poster'] = self.conf.user        params['file_ext[gistfile1]'] = self.conf.format #The format, for syntax hilighting        params['file_contents[gistfile1]'] = self.conf.content        params['file_name[gistfile1]'] = self.conf.title        return paramsclass YourpasteNetValidator(GenericPastebinValidator):    def validate(self):        YourpasteNetValidator.NOT_EMPTY_FIELDS.extend(['format', 'title'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['syntax'] = self.conf.format        params['name'] = self.conf.user        params['desc'] = self.conf.title        params['expire'] = "0" # Forever        params['code'] = self.conf.content        params['private'] = "0" # It's not a private post        params['remember'] = "0" # Cookies? ;)        params['page'] = "/paste"        params['regexp'] = '">http://yourpaste.net(.*)/</a>'        return paramsclass PasteyNetValidator(GenericPastebinValidator):    def parentFixup(self, website, parentid):        if parentid == "":            return ""        url_opener = pasteURLopener()        page = url_opener.open(website + '/' + parentid, None)        matches = re.split('<input.*?name="parent".*?value="(.*?)"', page.read())        if len(matches) <= 1 or re.match(parentid, matches[1]) == None:            # The obfuscated version didn't begin with the partial version,            # or unable to find the obfuscated version for some reason!            # Create a paste with no parent (should we throw, instead?)            return ""        return matches[1]    def validate(self):        PasteyNetValidator.NOT_EMPTY_FIELDS.extend(['format','title'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['author'] = self.conf.user        params['subject'] = self.conf.title        params['parent'] = self.parentFixup(self.conf.website, self.conf.parentpid)        params['text'] = self.conf.content        params['language'] = self.conf.format        params['paste'] = "Paste"        params['page'] = '/submit.php'        params['regexp'] = '">http://(?:(?:[a-zA-Z0-9\-_\.]*)(?:pastey\.net))(/.*)</a>'        return paramsclass PastebinComValidator(GenericPastebinValidator):    def validate(self):        PastebinComValidator.NOT_EMPTY_FIELDS.extend(['format','version'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['poster'] = self.conf.user        params['code2'] = self.conf.content        params['version'] = self.conf.version        params['parent_pid'] = self.conf.parentpid #For reply, "" means homepage (new thread)        params['format'] = self.conf.format #The format, for syntax hilighting        params['paste'] = "Send"         params['remember'] = "0" #Do you want a cookie ?        params['expiry'] = "f" #The expiration, f = forever        return paramsclass PastebinCaValidator(GenericPastebinValidator):    def getParameters(self):        params = {}        params['name'] = self.conf.user        params['content'] = self.conf.content        params['type'] = "1" #The expiration, 1 = raw        params['save'] = "0" #Do you want a cookie ?        params['s'] = "Submit Post"        params['regexp'] = '">http://.*pastebin.ca/(.*)</a></p><p>'        return paramsclass RafbNetValidator(GenericPastebinValidator):    def validate(self):        RafbNetValidator.NOT_EMPTY_FIELDS.append('format')        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['page'] = "/paste/paste.php"        params['nick'] = self.conf.user        params['text'] = self.conf.content        params['lang'] = "Plain Text" #The format, for syntax hilighting        params['cvt_tabs'] = "No"        return paramsclass StikkedComValidator(GenericPastebinValidator):    def validate(self):        StikkedComValidator.NOT_EMPTY_FIELDS.extend(['title', 'format'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['name'] = self.conf.user        params['title'] = self.conf.title        params['email'] = ""        params['lang'] = self.conf.format #"text" #The format, for syntax hilighting        params['code'] = self.conf.content        params['website'] = ""        params['submit'] = "submit"        return paramsclass SlexyOrgValidator(GenericPastebinValidator):    def validate(self):        SlexyOrgValidator.NOT_EMPTY_FIELDS.extend(['title', 'format'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['page'] = "/index.php/submit"        params['raw_paste'] = self.conf.content        params['comment'] = ""        params['author'] = self.conf.user        params['language'] = self.conf.format #"text" #The format, for syntax hilighting        params['permissions'] = "0"        params['desc'] = self.conf.title        params['linenumbers'] = "0"        params['expire'] = "0"        params['submit'] = "Submit Paste"        return paramsclass FpasteValidator(GenericPastebinValidator):    def validate(self):        FpasteValidator.NOT_EMPTY_FIELDS.append('format')        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['lang'] = self.conf.format #The format, for syntax hilighting        params['page'] = "/paste/save"        params['content'] = self.conf.content        params['submit'] = "nautilus-pastebin"        return paramsclass Paste2OrgValidator(GenericPastebinValidator):    def validate(self):        Paste2OrgValidator.NOT_EMPTY_FIELDS.extend(['format','title'])        return GenericPastebinValidator.validate(self)    def getParameters(self):        params = {}        params['page'] = "/new-paste"        params['description'] = self.conf.title        params['lang'] = self.conf.format        params['code'] = self.conf.content        params['parent'] = "0"        return paramsclass ValidatorPluginLoader(object):    """Experimental feature"""    @staticmethod    def getValidatorPlugin(name):        sys.path.extend(getPluginsPath())        obj = None        stmt = """        from %(name)s import %(name)sValidator        obj = %(name)sValidator        """        exec(stmt % {'name' : name})        return obj    def __init__(self): raise NotImplementedErrorclass PastebinitExtension(nautilus.MenuProvider):    def __init__(self):        log ("Intializing Nautilus Pastebin extension...")        def get_file_items(self, window, files):        if len(files)!=1:            return        filename = files[0]                validator = ConfigurationValidator(getConfigurationFilename())        validator.validate()        pasteconf = validator.getPastebinConfiguration()        if not pasteconf.setFormatByMimeType(filename.get_mime_type()):            return        self.pasteconf = pasteconf        items = []        #Called when the user selects a file in Nautilus.        item = nautilus.MenuItem("NautilusPython::pastebin_item",                                 _("Pastebin"),                                 _("Pastebin this file"))        item.set_property('icon', "nautilus-pastebin")        item.connect("activate", self.menu_activate_cb, files)        items.append(item)        return items    def menu_activate_cb(self, menu, files):        if len(files) != 1:            return        filename = files[0]        if filename.get_uri_scheme() != 'file':            return        if filename.is_directory():            return        pastefile = urllib.unquote(filename.get_uri()[7:])        log (_("Trying to paste %s") % pastefile)        fp = open(pastefile)        content = fp.read()        fp.close()        # OK, let's go...        self.pasteconf.content = content        validator = PastebinValidatorFactory().getValidator(self.pasteconf)        if not validator.validate():            return        website = self.pasteconf.website        params = validator.getParameters()        if not re.search(".*/", website):            website += "/"        reLink=None        tmp_page=""        if params.__contains__("page"):            website+=params['page']            tmp_page=params['page']            params.__delitem__("page")        if params.__contains__("regexp"):            reLink=params['regexp']            params.__delitem__("regexp")        params = urllib.urlencode(params) #Convert to a format usable with the HTML POST        try:            url_opener = pasteURLopener()            page = url_opener.open(website, params) #Send the informations and be redirected to the final page            summary = 'File pasted to: '            pasteurl = '<a href="%(pasteurl)s">%(pasteurl)s</a>'            if reLink: #Check if we have to apply a regexp                website = website.replace(tmp_page, "")                message = pasteurl % { 'pasteurl' :                    website + "/" + re.split(reLink, page.read())[1] }            else:                message = pasteurl % { 'pasteurl': page.url }        except:            summary = _("Unable to read or parse the result page")            message = _("It could be a server timeout or a change server side, try later.")        finally:            n = pynotify.Notification(summary, message)            n.show()