diff options
Diffstat (limited to 'cherrypy/tutorial')
-rw-r--r-- | cherrypy/tutorial/README.txt | 16 | ||||
-rwxr-xr-x | cherrypy/tutorial/__init__.py | 3 | ||||
-rwxr-xr-x | cherrypy/tutorial/bonus-sqlobject.py | 168 | ||||
-rw-r--r-- | cherrypy/tutorial/custom_error.html | 14 | ||||
-rw-r--r-- | cherrypy/tutorial/pdf_file.pdf | bin | 85698 -> 0 bytes | |||
-rwxr-xr-x | cherrypy/tutorial/tut01_helloworld.py | 35 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut02_expose_methods.py | 32 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut03_get_and_post.py | 53 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut04_complex_site.py | 98 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut05_derived_objects.py | 83 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut06_default_method.py | 64 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut07_sessions.py | 44 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut08_generators_and_yield.py | 47 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut09_files.py | 107 | ||||
-rwxr-xr-x | cherrypy/tutorial/tut10_http_errors.py | 81 | ||||
-rw-r--r-- | cherrypy/tutorial/tutorial.conf | 4 |
16 files changed, 0 insertions, 849 deletions
diff --git a/cherrypy/tutorial/README.txt b/cherrypy/tutorial/README.txt deleted file mode 100644 index 2b877e1..0000000 --- a/cherrypy/tutorial/README.txt +++ /dev/null @@ -1,16 +0,0 @@ -CherryPy Tutorials
-------------------------------------------------------------------------
-
-This is a series of tutorials explaining how to develop dynamic web
-applications using CherryPy. A couple of notes:
-
- - Each of these tutorials builds on the ones before it. If you're
- new to CherryPy, we recommend you start with 01_helloworld.py and
- work your way upwards. :)
-
- - In most of these tutorials, you will notice that all output is done
- by returning normal Python strings, often using simple Python
- variable substitution. In most real-world applications, you will
- probably want to use a separate template package (like Cheetah,
- CherryTemplate or XML/XSL).
-
diff --git a/cherrypy/tutorial/__init__.py b/cherrypy/tutorial/__init__.py deleted file mode 100755 index c4e2c55..0000000 --- a/cherrypy/tutorial/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ - -# This is used in test_config to test unrepr of "from A import B" -thing2 = object()
\ No newline at end of file diff --git a/cherrypy/tutorial/bonus-sqlobject.py b/cherrypy/tutorial/bonus-sqlobject.py deleted file mode 100755 index c43feb4..0000000 --- a/cherrypy/tutorial/bonus-sqlobject.py +++ /dev/null @@ -1,168 +0,0 @@ -''' -Bonus Tutorial: Using SQLObject - -This is a silly little contacts manager application intended to -demonstrate how to use SQLObject from within a CherryPy2 project. It -also shows how to use inline Cheetah templates. - -SQLObject is an Object/Relational Mapper that allows you to access -data stored in an RDBMS in a pythonic fashion. You create data objects -as Python classes and let SQLObject take care of all the nasty details. - -This code depends on the latest development version (0.6+) of SQLObject. -You can get it from the SQLObject Subversion server. You can find all -necessary information at <http://www.sqlobject.org>. This code will NOT -work with the 0.5.x version advertised on their website! - -This code also depends on a recent version of Cheetah. You can find -Cheetah at <http://www.cheetahtemplate.org>. - -After starting this application for the first time, you will need to -access the /reset URI in order to create the database table and some -sample data. Accessing /reset again will drop and re-create the table, -so you may want to be careful. :-) - -This application isn't supposed to be fool-proof, it's not even supposed -to be very GOOD. Play around with it some, browse the source code, smile. - -:) - --- Hendrik Mans <hendrik@mans.de> -''' - -import cherrypy -from Cheetah.Template import Template -from sqlobject import * - -# configure your database connection here -__connection__ = 'mysql://root:@localhost/test' - -# this is our (only) data class. -class Contact(SQLObject): - lastName = StringCol(length = 50, notNone = True) - firstName = StringCol(length = 50, notNone = True) - phone = StringCol(length = 30, notNone = True, default = '') - email = StringCol(length = 30, notNone = True, default = '') - url = StringCol(length = 100, notNone = True, default = '') - - -class ContactManager: - def index(self): - # Let's display a list of all stored contacts. - contacts = Contact.select() - - template = Template(''' - <h2>All Contacts</h2> - - #for $contact in $contacts - <a href="mailto:$contact.email">$contact.lastName, $contact.firstName</a> - [<a href="./edit?id=$contact.id">Edit</a>] - [<a href="./delete?id=$contact.id">Delete</a>] - <br/> - #end for - - <p>[<a href="./edit">Add new contact</a>]</p> - ''', [locals(), globals()]) - - return template.respond() - - index.exposed = True - - - def edit(self, id = 0): - # we really want id as an integer. Since GET/POST parameters - # are always passed as strings, let's convert it. - id = int(id) - - if id > 0: - # if an id is specified, we're editing an existing contact. - contact = Contact.get(id) - title = "Edit Contact" - else: - # if no id is specified, we're entering a new contact. - contact = None - title = "New Contact" - - - # In the following template code, please note that we use - # Cheetah's $getVar() construct for the form values. We have - # to do this because contact may be set to None (see above). - template = Template(''' - <h2>$title</h2> - - <form action="./store" method="POST"> - <input type="hidden" name="id" value="$id" /> - Last Name: <input name="lastName" value="$getVar('contact.lastName', '')" /><br/> - First Name: <input name="firstName" value="$getVar('contact.firstName', '')" /><br/> - Phone: <input name="phone" value="$getVar('contact.phone', '')" /><br/> - Email: <input name="email" value="$getVar('contact.email', '')" /><br/> - URL: <input name="url" value="$getVar('contact.url', '')" /><br/> - <input type="submit" value="Store" /> - </form> - ''', [locals(), globals()]) - - return template.respond() - - edit.exposed = True - - - def delete(self, id): - # Delete the specified contact - contact = Contact.get(int(id)) - contact.destroySelf() - return 'Deleted. <a href="./">Return to Index</a>' - - delete.exposed = True - - - def store(self, lastName, firstName, phone, email, url, id = None): - if id and int(id) > 0: - # If an id was specified, update an existing contact. - contact = Contact.get(int(id)) - - # We could set one field after another, but that would - # cause multiple UPDATE clauses. So we'll just do it all - # in a single pass through the set() method. - contact.set( - lastName = lastName, - firstName = firstName, - phone = phone, - email = email, - url = url) - else: - # Otherwise, add a new contact. - contact = Contact( - lastName = lastName, - firstName = firstName, - phone = phone, - email = email, - url = url) - - return 'Stored. <a href="./">Return to Index</a>' - - store.exposed = True - - - def reset(self): - # Drop existing table - Contact.dropTable(True) - - # Create new table - Contact.createTable() - - # Create some sample data - Contact( - firstName = 'Hendrik', - lastName = 'Mans', - email = 'hendrik@mans.de', - phone = '++49 89 12345678', - url = 'http://www.mornography.de') - - return "reset completed!" - - reset.exposed = True - - -print("If you're running this application for the first time, please go to http://localhost:8080/reset once in order to create the database!") - -cherrypy.quickstart(ContactManager()) diff --git a/cherrypy/tutorial/custom_error.html b/cherrypy/tutorial/custom_error.html deleted file mode 100644 index d0f30c8..0000000 --- a/cherrypy/tutorial/custom_error.html +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html> -<head> - <title>403 Unauthorized</title> -</head> - <body> - <h2>You can't do that!</h2> - <p>%(message)s</p> - <p>This is a custom error page that is read from a file.<p> - <pre>%(traceback)s</pre> - </body> -</html> diff --git a/cherrypy/tutorial/pdf_file.pdf b/cherrypy/tutorial/pdf_file.pdf Binary files differdeleted file mode 100644 index 38b4f15..0000000 --- a/cherrypy/tutorial/pdf_file.pdf +++ /dev/null diff --git a/cherrypy/tutorial/tut01_helloworld.py b/cherrypy/tutorial/tut01_helloworld.py deleted file mode 100755 index ef94760..0000000 --- a/cherrypy/tutorial/tut01_helloworld.py +++ /dev/null @@ -1,35 +0,0 @@ -""" -Tutorial - Hello World - -The most basic (working) CherryPy application possible. -""" - -# Import CherryPy global namespace -import cherrypy - -class HelloWorld: - """ Sample request handler class. """ - - def index(self): - # CherryPy will call this method for the root URI ("/") and send - # its return value to the client. Because this is tutorial - # lesson number 01, we'll just send something really simple. - # How about... - return "Hello world!" - - # Expose the index method through the web. CherryPy will never - # publish methods that don't have the exposed attribute set to True. - index.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(HelloWorld(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(HelloWorld(), config=tutconf) diff --git a/cherrypy/tutorial/tut02_expose_methods.py b/cherrypy/tutorial/tut02_expose_methods.py deleted file mode 100755 index 600fca3..0000000 --- a/cherrypy/tutorial/tut02_expose_methods.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -Tutorial - Multiple methods - -This tutorial shows you how to link to other methods of your request -handler. -""" - -import cherrypy - -class HelloWorld: - - def index(self): - # Let's link to another method here. - return 'We have an <a href="showMessage">important message</a> for you!' - index.exposed = True - - def showMessage(self): - # Here's the important message! - return "Hello world!" - showMessage.exposed = True - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(HelloWorld(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(HelloWorld(), config=tutconf) diff --git a/cherrypy/tutorial/tut03_get_and_post.py b/cherrypy/tutorial/tut03_get_and_post.py deleted file mode 100755 index 283477d..0000000 --- a/cherrypy/tutorial/tut03_get_and_post.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Tutorial - Passing variables - -This tutorial shows you how to pass GET/POST variables to methods. -""" - -import cherrypy - - -class WelcomePage: - - def index(self): - # Ask for the user's name. - return ''' - <form action="greetUser" method="GET"> - What is your name? - <input type="text" name="name" /> - <input type="submit" /> - </form>''' - index.exposed = True - - def greetUser(self, name = None): - # CherryPy passes all GET and POST variables as method parameters. - # It doesn't make a difference where the variables come from, how - # large their contents are, and so on. - # - # You can define default parameter values as usual. In this - # example, the "name" parameter defaults to None so we can check - # if a name was actually specified. - - if name: - # Greet the user! - return "Hey %s, what's up?" % name - else: - if name is None: - # No name was specified - return 'Please enter your name <a href="./">here</a>.' - else: - return 'No, really, enter your name <a href="./">here</a>.' - greetUser.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(WelcomePage(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(WelcomePage(), config=tutconf) diff --git a/cherrypy/tutorial/tut04_complex_site.py b/cherrypy/tutorial/tut04_complex_site.py deleted file mode 100755 index b4d820e..0000000 --- a/cherrypy/tutorial/tut04_complex_site.py +++ /dev/null @@ -1,98 +0,0 @@ -""" -Tutorial - Multiple objects - -This tutorial shows you how to create a site structure through multiple -possibly nested request handler objects. -""" - -import cherrypy - - -class HomePage: - def index(self): - return ''' - <p>Hi, this is the home page! Check out the other - fun stuff on this site:</p> - - <ul> - <li><a href="/joke/">A silly joke</a></li> - <li><a href="/links/">Useful links</a></li> - </ul>''' - index.exposed = True - - -class JokePage: - def index(self): - return ''' - <p>"In Python, how do you create a string of random - characters?" -- "Read a Perl file!"</p> - <p>[<a href="../">Return</a>]</p>''' - index.exposed = True - - -class LinksPage: - def __init__(self): - # Request handler objects can create their own nested request - # handler objects. Simply create them inside their __init__ - # methods! - self.extra = ExtraLinksPage() - - def index(self): - # Note the way we link to the extra links page (and back). - # As you can see, this object doesn't really care about its - # absolute position in the site tree, since we use relative - # links exclusively. - return ''' - <p>Here are some useful links:</p> - - <ul> - <li><a href="http://www.cherrypy.org">The CherryPy Homepage</a></li> - <li><a href="http://www.python.org">The Python Homepage</a></li> - </ul> - - <p>You can check out some extra useful - links <a href="./extra/">here</a>.</p> - - <p>[<a href="../">Return</a>]</p> - ''' - index.exposed = True - - -class ExtraLinksPage: - def index(self): - # Note the relative link back to the Links page! - return ''' - <p>Here are some extra useful links:</p> - - <ul> - <li><a href="http://del.icio.us">del.icio.us</a></li> - <li><a href="http://www.mornography.de">Hendrik's weblog</a></li> - </ul> - - <p>[<a href="../">Return to links page</a>]</p>''' - index.exposed = True - - -# Of course we can also mount request handler objects right here! -root = HomePage() -root.joke = JokePage() -root.links = LinksPage() - -# Remember, we don't need to mount ExtraLinksPage here, because -# LinksPage does that itself on initialization. In fact, there is -# no reason why you shouldn't let your root object take care of -# creating all contained request handler objects. - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(root, config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(root, config=tutconf) - diff --git a/cherrypy/tutorial/tut05_derived_objects.py b/cherrypy/tutorial/tut05_derived_objects.py deleted file mode 100755 index 3d4ec9b..0000000 --- a/cherrypy/tutorial/tut05_derived_objects.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -Tutorial - Object inheritance - -You are free to derive your request handler classes from any base -class you wish. In most real-world applications, you will probably -want to create a central base class used for all your pages, which takes -care of things like printing a common page header and footer. -""" - -import cherrypy - - -class Page: - # Store the page title in a class attribute - title = 'Untitled Page' - - def header(self): - return ''' - <html> - <head> - <title>%s</title> - <head> - <body> - <h2>%s</h2> - ''' % (self.title, self.title) - - def footer(self): - return ''' - </body> - </html> - ''' - - # Note that header and footer don't get their exposed attributes - # set to True. This isn't necessary since the user isn't supposed - # to call header or footer directly; instead, we'll call them from - # within the actually exposed handler methods defined in this - # class' subclasses. - - -class HomePage(Page): - # Different title for this page - title = 'Tutorial 5' - - def __init__(self): - # create a subpage - self.another = AnotherPage() - - def index(self): - # Note that we call the header and footer methods inherited - # from the Page class! - return self.header() + ''' - <p> - Isn't this exciting? There's - <a href="./another/">another page</a>, too! - </p> - ''' + self.footer() - index.exposed = True - - -class AnotherPage(Page): - title = 'Another Page' - - def index(self): - return self.header() + ''' - <p> - And this is the amazing second page! - </p> - ''' + self.footer() - index.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(HomePage(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(HomePage(), config=tutconf) - diff --git a/cherrypy/tutorial/tut06_default_method.py b/cherrypy/tutorial/tut06_default_method.py deleted file mode 100755 index fe24f38..0000000 --- a/cherrypy/tutorial/tut06_default_method.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -Tutorial - The default method - -Request handler objects can implement a method called "default" that -is called when no other suitable method/object could be found. -Essentially, if CherryPy2 can't find a matching request handler object -for the given request URI, it will use the default method of the object -located deepest on the URI path. - -Using this mechanism you can easily simulate virtual URI structures -by parsing the extra URI string, which you can access through -cherrypy.request.virtualPath. - -The application in this tutorial simulates an URI structure looking -like /users/<username>. Since the <username> bit will not be found (as -there are no matching methods), it is handled by the default method. -""" - -import cherrypy - - -class UsersPage: - - def index(self): - # Since this is just a stupid little example, we'll simply - # display a list of links to random, made-up users. In a real - # application, this could be generated from a database result set. - return ''' - <a href="./remi">Remi Delon</a><br/> - <a href="./hendrik">Hendrik Mans</a><br/> - <a href="./lorenzo">Lorenzo Lamas</a><br/> - ''' - index.exposed = True - - def default(self, user): - # Here we react depending on the virtualPath -- the part of the - # path that could not be mapped to an object method. In a real - # application, we would probably do some database lookups here - # instead of the silly if/elif/else construct. - if user == 'remi': - out = "Remi Delon, CherryPy lead developer" - elif user == 'hendrik': - out = "Hendrik Mans, CherryPy co-developer & crazy German" - elif user == 'lorenzo': - out = "Lorenzo Lamas, famous actor and singer!" - else: - out = "Unknown user. :-(" - - return '%s (<a href="./">back</a>)' % out - default.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(UsersPage(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(UsersPage(), config=tutconf) - diff --git a/cherrypy/tutorial/tut07_sessions.py b/cherrypy/tutorial/tut07_sessions.py deleted file mode 100755 index 4b1386b..0000000 --- a/cherrypy/tutorial/tut07_sessions.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Tutorial - Sessions - -Storing session data in CherryPy applications is very easy: cherrypy -provides a dictionary called "session" that represents the session -data for the current user. If you use RAM based sessions, you can store -any kind of object into that dictionary; otherwise, you are limited to -objects that can be pickled. -""" - -import cherrypy - - -class HitCounter: - - _cp_config = {'tools.sessions.on': True} - - def index(self): - # Increase the silly hit counter - count = cherrypy.session.get('count', 0) + 1 - - # Store the new value in the session dictionary - cherrypy.session['count'] = count - - # And display a silly hit count message! - return ''' - During your current session, you've viewed this - page %s times! Your life is a patio of fun! - ''' % count - index.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(HitCounter(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(HitCounter(), config=tutconf) - diff --git a/cherrypy/tutorial/tut08_generators_and_yield.py b/cherrypy/tutorial/tut08_generators_and_yield.py deleted file mode 100755 index a6fbdc2..0000000 --- a/cherrypy/tutorial/tut08_generators_and_yield.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -Bonus Tutorial: Using generators to return result bodies - -Instead of returning a complete result string, you can use the yield -statement to return one result part after another. This may be convenient -in situations where using a template package like CherryPy or Cheetah -would be overkill, and messy string concatenation too uncool. ;-) -""" - -import cherrypy - - -class GeneratorDemo: - - def header(self): - return "<html><body><h2>Generators rule!</h2>" - - def footer(self): - return "</body></html>" - - def index(self): - # Let's make up a list of users for presentation purposes - users = ['Remi', 'Carlos', 'Hendrik', 'Lorenzo Lamas'] - - # Every yield line adds one part to the total result body. - yield self.header() - yield "<h3>List of users:</h3>" - - for user in users: - yield "%s<br/>" % user - - yield self.footer() - index.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(GeneratorDemo(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(GeneratorDemo(), config=tutconf) - diff --git a/cherrypy/tutorial/tut09_files.py b/cherrypy/tutorial/tut09_files.py deleted file mode 100755 index 4c8e581..0000000 --- a/cherrypy/tutorial/tut09_files.py +++ /dev/null @@ -1,107 +0,0 @@ -""" - -Tutorial: File upload and download - -Uploads -------- - -When a client uploads a file to a CherryPy application, it's placed -on disk immediately. CherryPy will pass it to your exposed method -as an argument (see "myFile" below); that arg will have a "file" -attribute, which is a handle to the temporary uploaded file. -If you wish to permanently save the file, you need to read() -from myFile.file and write() somewhere else. - -Note the use of 'enctype="multipart/form-data"' and 'input type="file"' -in the HTML which the client uses to upload the file. - - -Downloads ---------- - -If you wish to send a file to the client, you have two options: -First, you can simply return a file-like object from your page handler. -CherryPy will read the file and serve it as the content (HTTP body) -of the response. However, that doesn't tell the client that -the response is a file to be saved, rather than displayed. -Use cherrypy.lib.static.serve_file for that; it takes four -arguments: - -serve_file(path, content_type=None, disposition=None, name=None) - -Set "name" to the filename that you expect clients to use when they save -your file. Note that the "name" argument is ignored if you don't also -provide a "disposition" (usually "attachement"). You can manually set -"content_type", but be aware that if you also use the encoding tool, it -may choke if the file extension is not recognized as belonging to a known -Content-Type. Setting the content_type to "application/x-download" works -in most cases, and should prompt the user with an Open/Save dialog in -popular browsers. - -""" - -import os -localDir = os.path.dirname(__file__) -absDir = os.path.join(os.getcwd(), localDir) - -import cherrypy -from cherrypy.lib import static - - -class FileDemo(object): - - def index(self): - return """ - <html><body> - <h2>Upload a file</h2> - <form action="upload" method="post" enctype="multipart/form-data"> - filename: <input type="file" name="myFile" /><br /> - <input type="submit" /> - </form> - <h2>Download a file</h2> - <a href='download'>This one</a> - </body></html> - """ - index.exposed = True - - def upload(self, myFile): - out = """<html> - <body> - myFile length: %s<br /> - myFile filename: %s<br /> - myFile mime-type: %s - </body> - </html>""" - - # Although this just counts the file length, it demonstrates - # how to read large files in chunks instead of all at once. - # CherryPy reads the uploaded file into a temporary file; - # myFile.file.read reads from that. - size = 0 - while True: - data = myFile.file.read(8192) - if not data: - break - size += len(data) - - return out % (size, myFile.filename, myFile.content_type) - upload.exposed = True - - def download(self): - path = os.path.join(absDir, "pdf_file.pdf") - return static.serve_file(path, "application/x-download", - "attachment", os.path.basename(path)) - download.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(FileDemo(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(FileDemo(), config=tutconf) diff --git a/cherrypy/tutorial/tut10_http_errors.py b/cherrypy/tutorial/tut10_http_errors.py deleted file mode 100755 index dfa5733..0000000 --- a/cherrypy/tutorial/tut10_http_errors.py +++ /dev/null @@ -1,81 +0,0 @@ -""" - -Tutorial: HTTP errors - -HTTPError is used to return an error response to the client. -CherryPy has lots of options regarding how such errors are -logged, displayed, and formatted. - -""" - -import os -localDir = os.path.dirname(__file__) -curpath = os.path.normpath(os.path.join(os.getcwd(), localDir)) - -import cherrypy - - -class HTTPErrorDemo(object): - - # Set a custom response for 403 errors. - _cp_config = {'error_page.403' : os.path.join(curpath, "custom_error.html")} - - def index(self): - # display some links that will result in errors - tracebacks = cherrypy.request.show_tracebacks - if tracebacks: - trace = 'off' - else: - trace = 'on' - - return """ - <html><body> - <p>Toggle tracebacks <a href="toggleTracebacks">%s</a></p> - <p><a href="/doesNotExist">Click me; I'm a broken link!</a></p> - <p><a href="/error?code=403">Use a custom error page from a file.</a></p> - <p>These errors are explicitly raised by the application:</p> - <ul> - <li><a href="/error?code=400">400</a></li> - <li><a href="/error?code=401">401</a></li> - <li><a href="/error?code=402">402</a></li> - <li><a href="/error?code=500">500</a></li> - </ul> - <p><a href="/messageArg">You can also set the response body - when you raise an error.</a></p> - </body></html> - """ % trace - index.exposed = True - - def toggleTracebacks(self): - # simple function to toggle tracebacks on and off - tracebacks = cherrypy.request.show_tracebacks - cherrypy.config.update({'request.show_tracebacks': not tracebacks}) - - # redirect back to the index - raise cherrypy.HTTPRedirect('/') - toggleTracebacks.exposed = True - - def error(self, code): - # raise an error based on the get query - raise cherrypy.HTTPError(status = code) - error.exposed = True - - def messageArg(self): - message = ("If you construct an HTTPError with a 'message' " - "argument, it wil be placed on the error page " - "(underneath the status line by default).") - raise cherrypy.HTTPError(500, message=message) - messageArg.exposed = True - - -import os.path -tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') - -if __name__ == '__main__': - # CherryPy always starts with app.root when trying to map request URIs - # to objects, so we need to mount a request handler root. A request - # to '/' will be mapped to HelloWorld().index(). - cherrypy.quickstart(HTTPErrorDemo(), config=tutconf) -else: - # This branch is for the test suite; you can ignore it. - cherrypy.tree.mount(HTTPErrorDemo(), config=tutconf) diff --git a/cherrypy/tutorial/tutorial.conf b/cherrypy/tutorial/tutorial.conf deleted file mode 100644 index 6537fd3..0000000 --- a/cherrypy/tutorial/tutorial.conf +++ /dev/null @@ -1,4 +0,0 @@ -[global]
-server.socket_host = "127.0.0.1"
-server.socket_port = 8080
-server.thread_pool = 10
|