On 10/22/06, Lee McFadden <[EMAIL PROTECTED]> wrote:
>
> On 10/21/06, Jorge Vargas <[EMAIL PROTECTED]> wrote:
> >
> >
> > Does it has a json interface? I have this little script call nopaste
> > that you give it a file and it does the paste for you. which by the
> > way is the only reason I have ruby on my gentoo box,
> > I have been wanting to port it so I can delete that runtime (nothing
> > agains it :)
>
> That was something I was thinking about the other day.  I'd like to be
> able to paste stuff from TextMate.
> >
ok I took a shot at it, I had to patch your code to get me an entry
point that will return the id, i could had use the secret_paste_count
(shh don't tell anyone) but that will mean that maybe I could get the
wrong number if 2 people post to close to each other.

And of course applying the "lets not reinvent the wheel" I hop on a
module to do the sending from the python cookbook

tell me if you like it


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears
-~----------~----~----~----~------~----~------~--~---
Index: stickum/release.py
===================================================================
--- stickum/release.py  (revision 6)
+++ stickum/release.py  (working copy)
@@ -1,6 +1,6 @@
 # Release information about stickum
 
-version = "1.0"
+version = "0.1"
 
 # description = "Your plan to rule the world"
 # long_description = "More description about your plan"
Index: stickum/controllers.py
===================================================================
--- stickum/controllers.py      (revision 6)
+++ stickum/controllers.py      (working copy)
@@ -36,8 +36,16 @@
         paste.flush()
         raise redirect("/paste/%d" % paste.id)
             
-        
     @expose()
+    def save_cli(self, content, lang, submit):
+        paste = model.Paste()
+        paste.content = content
+        paste.lang = lang
+        paste.pasted_on = datetime.now()
+        paste.flush()
+        return turbogears.url("/paste/%d" % paste.id)
+
+    @expose()
     def default(self, id, action="view", *args, **kw):
         try:
             id = int(id)
Index: setup.py
===================================================================
--- setup.py    (revision 6)
+++ setup.py    (working copy)
@@ -18,6 +18,8 @@
     
     install_requires = [
         "TurboGears >= 1.0b1",
+        "SQLAlchemy",
+        #"SilverCity" #CURRENTLY BROKEN
     ],
     scripts = ["start-stickum.py"],
     zip_safe=False,
@@ -41,7 +43,7 @@
         # 'python.templating.engines',
         
         # If this is a full application, uncomment the next line
-        # 'turbogears.app',
+         'turbogears.app',
     ],
     classifiers = [
         'Development Status :: 3 - Alpha',
@@ -51,7 +53,7 @@
         'Framework :: TurboGears',
         # if this is an application that you'll distribute through
         # the Cheeseshop, uncomment the next line
-        # 'Framework :: TurboGears :: Applications',
+         'Framework :: TurboGears :: Applications',
         
         # if this is a package that includes widgets that you'll distribute
         # through the Cheeseshop, uncomment the next line
Index: stickum.egg-info/SOURCES.txt
===================================================================
--- stickum.egg-info/SOURCES.txt        (revision 6)
+++ stickum.egg-info/SOURCES.txt        (working copy)
@@ -1,11 +1,17 @@
+LICENCE.txt
 README.txt
+dev.cfg
+sample-prod.cfg
 setup.py
+setup.pyc
 start-stickum.py
 stickum/__init__.py
 stickum/controllers.py
 stickum/json.py
 stickum/model.py
 stickum/release.py
+stickum/silvercity.py
+stickum/util.py
 stickum.egg-info/PKG-INFO
 stickum.egg-info/SOURCES.txt
 stickum.egg-info/dependency_links.txt
@@ -15,7 +21,22 @@
 stickum.egg-info/sqlobject.txt
 stickum.egg-info/top_level.txt
 stickum/config/__init__.py
+stickum/config/app.cfg
+stickum/config/log.cfg
+stickum/static/css/style.css
+stickum/static/images/favicon.ico
+stickum/static/images/header_inner.png
+stickum/static/images/info.png
+stickum/static/images/ok.png
+stickum/static/images/tg_under_the_hood.png
+stickum/static/images/under_the_hood_blue.png
 stickum/templates/__init__.py
+stickum/templates/index.kid
+stickum/templates/login.kid
+stickum/templates/master.kid
+stickum/templates/paste_copy.kid
+stickum/templates/paste_view.kid
+stickum/templates/welcome.kid
 stickum/tests/__init__.py
 stickum/tests/test_controllers.py
 stickum/tests/test_model.py
Index: stickum.egg-info/PKG-INFO
===================================================================
--- stickum.egg-info/PKG-INFO   (revision 6)
+++ stickum.egg-info/PKG-INFO   (working copy)
@@ -1,15 +1,17 @@
 Metadata-Version: 1.0
 Name: stickum
-Version: 1.0
+Version: 0.1
 Summary: UNKNOWN
 Home-page: UNKNOWN
 Author: UNKNOWN
 Author-email: UNKNOWN
 License: UNKNOWN
 Description: UNKNOWN
+Keywords: turbogears.app
 Platform: UNKNOWN
 Classifier: Development Status :: 3 - Alpha
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Framework :: TurboGears
+Classifier: Framework :: TurboGears :: Applications
Index: stickum.egg-info/requires.txt
===================================================================
--- stickum.egg-info/requires.txt       (revision 6)
+++ stickum.egg-info/requires.txt       (working copy)
@@ -1 +1,3 @@
-TurboGears >= 1.0b1
\ No newline at end of file
+TurboGears >= 1.0b1
+SQLAlchemy
+SilverCity
\ No newline at end of file
'''
__author__ = Jorge L. Vargas 

This is a commandline interface to a stickum server
defaults are set to point at paste.turbogears.org and post python code
run it with -h --help for options
'''

import MultipartPostHandler
import urllib2
#~ import cookielib

from optparse import OptionParser

#~ def post_with_password(url,params):
  #~ cookies = cookielib.CookieJar()
  #~ opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                #~ MultipartPostHandler.MultipartPostHandler)
  #~ assert username and password in params
  #~ return opener.open(url,params)

def post_without_password(url,params):
    opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler)
    return opener.open(url, params)

URL=r"http://paste.turbogears.org/paste/save_cli";
CHOICES=["Python",
            "HTML",
            "CSS",
            "JavaScript",
            "SQL",
            "XML",
            "ASP",
            "C++",
            "Perl",
            "PHP",
            "Ruby",
            "XSLT",
            "None"]
            
#allow lowercases too :)
#~ for choice in CHOICES:
    #~ CHOICES.append(choice.lower())

def main():
    usage = "usage: %prog [options] file1 file2 ... file3"
    version = "0.0.1"
    parser = OptionParser(usage=usage,version=version)
    parser.set_defaults(site=URL,lang='Python')
    parser.add_option("-s", "--site", dest="site",
                  help="Site to post to (default %s)" % URL)

    parser.add_option("-l", "--lang", dest="lang",type='choice',choices=CHOICES,
                  help="the language in which the code is written")

    parser.add_option("-u", "--user", dest="username",
                  help="username for autentication")

    parser.add_option("-p", "--pass", dest="password",
                  help="password for user")

    (options, args) = parser.parse_args()

    if options.username and not options.password:
        parser.error("you must provide a username and password")
    if not args:
        parser.error("you need to provide at least 1 filename")
    
    for f in args:
        params={"lang" : options.lang,
                "content" : unicode(open(f,'rb').read()),
                "submit" : "Paste it!"
                }
        output=""
        if options.username and options.password:
            params['username']=options.username
            params['password']=options.password
            output=post_with_password(options.url,params)
        else:
            output=post_without_password(options.site,params)

        #I guess there is no webpath in the eggs deployed at tg.org since there is none at the config...
        print  "http://paste.turbogears.org"+output.read() + "\n"

if __name__ == "__main__":
    main()
#!/usr/bin/python

####
# 02/2006 Will Holcomb <[EMAIL PROTECTED]>
# 
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# 
# This library 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
# Lesser General Public License for more details.
#
"""
Usage:
  Enables the use of multipart/form-data for posting forms

Inspirations:
  Upload files in python:
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
  urllib2_file:
    Fabien Seisen: <[EMAIL PROTECTED]>

Example:
  import MultipartPostHandler, urllib2, cookielib

  cookies = cookielib.CookieJar()
  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                MultipartPostHandler.MultipartPostHandler)
  params = { "username" : "bob", "password" : "riviera",
             "file" : open("filename", "rb") }
  opener.open("http://wwww.bobsite.com/upload/";, params)

Further Example:
  The main function of this file is a sample which downloads a page and
  then uploads it to the W3C validator.
"""

import urllib
import urllib2
import mimetools, mimetypes
import os, stat

class Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable

# Controls how sequences are uncoded. If true, elements may be given multiple values by
#  assigning a sequence.
doseq = 1

class MultipartPostHandler(urllib2.BaseHandler):
    handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first

    def http_request(self, request):
        data = request.get_data()
        if data is not None and type(data) != str:
            v_files = []
            v_vars = []
            try:
                 for(key, value) in data.items():
                     if type(value) == file:
                         v_files.append((key, value))
                     else:
                         v_vars.append((key, value))
            except TypeError:
                systype, value, traceback = sys.exc_info()
                raise TypeError, "not a valid non-string sequence or mapping object", traceback

            if len(v_files) == 0:
                data = urllib.urlencode(v_vars, doseq)
            else:
                boundary, data = self.multipart_encode(v_vars, v_files)
                contenttype = 'multipart/form-data; boundary=%s' % boundary
                if(request.has_header('Content-Type')
                   and request.get_header('Content-Type').find('multipart/form-data') != 0):
                    print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data')
                request.add_unredirected_header('Content-Type', contenttype)

            request.add_data(data)
        return request

    def multipart_encode(vars, files, boundary = None, buffer = None):
        if boundary is None:
            boundary = mimetools.choose_boundary()
        if buffer is None:
            buffer = ''
        for(key, value) in vars:
            buffer += '--%s\r\n' % boundary
            buffer += 'Content-Disposition: form-data; name="%s"' % key
            buffer += '\r\n\r\n' + value + '\r\n'
        for(key, fd) in files:
            file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
            filename = fd.name.split('/')[-1]
            contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
            buffer += '--%s\r\n' % boundary
            buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename)
            buffer += 'Content-Type: %s\r\n' % contenttype
            # buffer += 'Content-Length: %s\r\n' % file_size
            fd.seek(0)
            buffer += '\r\n' + fd.read() + '\r\n'
        buffer += '--%s--\r\n\r\n' % boundary
        return boundary, buffer
    multipart_encode = Callable(multipart_encode)

    https_request = http_request

def main():
    import tempfile, sys

    validatorURL = "http://validator.w3.org/check";
    opener = urllib2.build_opener(MultipartPostHandler)

    def validateFile(url):
        temp = tempfile.mkstemp(suffix=".html")
        os.write(temp[0], opener.open(url).read())
        params = { "ss" : "0",            # show source
                   "doctype" : "Inline",
                   "uploaded_file" : open(temp[1], "rb") }
        print opener.open(validatorURL, params).read()
        os.remove(temp[1])

    if len(sys.argv[1:]) > 0:
        for arg in sys.argv[1:]:
            validateFile(arg)
    else:
        validateFile("http://www.google.com";)

if __name__=="__main__":
    main()

Reply via email to