1
0
mirror of https://github.com/Tygs/0bin.git synced 2023-08-10 21:13:00 +03:00

Porting zerobin to python 3

This commit is contained in:
sametmax
2015-05-10 19:19:02 +02:00
parent 391df055f9
commit 9b84122414
137 changed files with 22928 additions and 4370 deletions

View File

@ -0,0 +1,16 @@
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).

View File

@ -0,0 +1,3 @@
# This is used in test_config to test unrepr of "from A import B"
thing2 = object()

View File

@ -0,0 +1,14 @@
<?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>

Binary file not shown.

View File

@ -0,0 +1,37 @@
"""
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)

View File

@ -0,0 +1,33 @@
"""
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="show_msg">important message</a> for you!'
index.exposed = True
def show_msg(self):
# Here's the important message!
return "Hello world!"
show_msg.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)

View File

@ -0,0 +1,53 @@
"""
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)

View File

@ -0,0 +1,105 @@
"""
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.cherrypy.org">CherryPy</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)

View File

@ -0,0 +1,82 @@
"""
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)

View File

@ -0,0 +1,63 @@
"""
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)

View File

@ -0,0 +1,43 @@
"""
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)

View File

@ -0,0 +1,46 @@
"""
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)

View File

@ -0,0 +1,107 @@
"""
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)

View File

@ -0,0 +1,86 @@
"""
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)

View File

@ -0,0 +1,4 @@
[global]
server.socket_host = "127.0.0.1"
server.socket_port = 8080
server.thread_pool = 10