├── .gitignore ├── AUTHORS ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Procfile ├── README.md ├── app ├── apiclient ├── app.yaml ├── appengine_config.py ├── cherrypy ├── cloudstorage ├── dateutil │ ├── __init__.py │ ├── easter.py │ ├── parser.py │ ├── relativedelta.py │ ├── rrule.py │ ├── tz.py │ ├── tzwin.py │ └── zoneinfo │ │ ├── __init__.py │ │ └── zoneinfo--latest.tar.gz ├── decorator.py ├── feedgen ├── gfm ├── handlers │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── package_uploaders.py │ │ ├── package_versions.py │ │ ├── packages.py │ │ └── root.py │ ├── cloud_storage.py │ ├── doc.py │ ├── feed.py │ ├── package_uploaders.py │ ├── package_versions.py │ ├── packages.py │ ├── pager.py │ ├── private_keys.py │ ├── root.py │ └── search.py ├── httplib2 ├── index.yaml ├── markdown ├── mdx_gfm ├── mdx_partial_gfm ├── models │ ├── __init__.py │ ├── package.py │ ├── package_version.py │ ├── private_key.py │ ├── properties.py │ ├── pubspec.py │ ├── readme.py │ └── semantic_version.py ├── oauth2client ├── pub_dartlang.py ├── pygments ├── pystache ├── repoze ├── routes ├── six.py ├── static │ ├── favicon.ico │ ├── img │ │ ├── assets-and-transformers.png │ │ ├── dart-logo-400x400.png │ │ ├── dart.png │ │ ├── glyphicons-halflings-white.png │ │ ├── glyphicons-halflings.png │ │ └── input-and-output-assets.png │ ├── js │ │ ├── bootstrap-dropdown.js │ │ ├── bootstrap-tab.js │ │ ├── jquery-1.7.2.min.js │ │ └── script.js │ └── style.css ├── uritemplate ├── views │ ├── admin.mustache │ ├── authorized.mustache │ ├── error.mustache │ ├── index.mustache │ ├── layout.mustache │ ├── packages │ │ ├── index.mustache │ │ ├── show.mustache │ │ └── versions │ │ │ └── index.mustache │ ├── pagination.mustache │ ├── private_keys │ │ └── new.mustache │ ├── search.mustache │ └── site_map.mustache └── yaml ├── codereview.settings ├── css ├── config.rb └── sass │ ├── _syntax.scss │ └── style.scss ├── test.py ├── test ├── test_handlers │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── test_package_uploaders.py │ │ ├── test_package_versions.py │ │ ├── test_packages.py │ │ └── test_version_negotiation.py │ ├── test_error.py │ ├── test_package_uploaders.py │ ├── test_package_versions.py │ ├── test_packages.py │ ├── test_private_keys.py │ ├── test_root.py │ └── test_search.py ├── test_models │ ├── __init__.py │ ├── test_models.py │ ├── test_package.py │ ├── test_package_version.py │ ├── test_pubspec.py │ ├── test_readme.py │ └── test_semantic_version.py └── testcase.py └── third_party ├── apiclient ├── __init__.py ├── channel.py ├── discovery.py ├── errors.py ├── http.py ├── mimeparse.py ├── model.py ├── sample_tools.py └── schema.py ├── cherrypy ├── LICENSE.txt ├── __init__.py ├── _cpchecker.py ├── _cpcompat.py ├── _cpconfig.py ├── _cpdispatch.py ├── _cperror.py ├── _cplogging.py ├── _cpmodpy.py ├── _cpnative_server.py ├── _cpreqbody.py ├── _cprequest.py ├── _cpserver.py ├── _cpthreadinglocal.py ├── _cptools.py ├── _cptree.py ├── _cpwsgi.py ├── _cpwsgi_server.py ├── cherryd ├── favicon.ico ├── lib │ ├── __init__.py │ ├── auth.py │ ├── auth_basic.py │ ├── auth_digest.py │ ├── caching.py │ ├── covercp.py │ ├── cpstats.py │ ├── cptools.py │ ├── encoding.py │ ├── gctools.py │ ├── http.py │ ├── httpauth.py │ ├── httputil.py │ ├── jsontools.py │ ├── profiler.py │ ├── reprconf.py │ ├── sessions.py │ ├── static.py │ └── xmlrpcutil.py ├── process │ ├── __init__.py │ ├── plugins.py │ ├── servers.py │ ├── win32.py │ └── wspbus.py ├── scaffold │ ├── __init__.py │ ├── apache-fcgi.conf │ ├── example.conf │ ├── site.conf │ └── static │ │ └── made_with_cherrypy_small.png ├── test │ ├── __init__.py │ ├── _test_decorators.py │ ├── _test_states_demo.py │ ├── benchmark.py │ ├── checkerdemo.py │ ├── helper.py │ ├── logtest.py │ ├── modfastcgi.py │ ├── modfcgid.py │ ├── modpy.py │ ├── modwsgi.py │ ├── sessiondemo.py │ ├── static │ │ ├── dirback.jpg │ │ ├── has space.html │ │ └── index.html │ ├── style.css │ ├── test.pem │ ├── test_auth_basic.py │ ├── test_auth_digest.py │ ├── test_bus.py │ ├── test_caching.py │ ├── test_config.py │ ├── test_config_server.py │ ├── test_conn.py │ ├── test_core.py │ ├── test_dynamicobjectmapping.py │ ├── test_encoding.py │ ├── test_etags.py │ ├── test_http.py │ ├── test_httpauth.py │ ├── test_httplib.py │ ├── test_json.py │ ├── test_logging.py │ ├── test_mime.py │ ├── test_misc_tools.py │ ├── test_objectmapping.py │ ├── test_proxy.py │ ├── test_refleaks.py │ ├── test_request_obj.py │ ├── test_routes.py │ ├── test_session.py │ ├── test_sessionauthenticate.py │ ├── test_states.py │ ├── test_static.py │ ├── test_tools.py │ ├── test_tutorials.py │ ├── test_virtualhost.py │ ├── test_wsgi_ns.py │ ├── test_wsgi_vhost.py │ ├── test_wsgiapps.py │ ├── test_xmlrpc.py │ └── webtest.py ├── tutorial │ ├── README.txt │ ├── __init__.py │ ├── bonus-sqlobject.py │ ├── custom_error.html │ ├── pdf_file.pdf │ ├── tut01_helloworld.py │ ├── tut02_expose_methods.py │ ├── tut03_get_and_post.py │ ├── tut04_complex_site.py │ ├── tut05_derived_objects.py │ ├── tut06_default_method.py │ ├── tut07_sessions.py │ ├── tut08_generators_and_yield.py │ ├── tut09_files.py │ ├── tut10_http_errors.py │ └── tutorial.conf └── wsgiserver │ ├── __init__.py │ ├── ssl_builtin.py │ ├── ssl_pyopenssl.py │ ├── wsgiserver2.py │ └── wsgiserver3.py ├── cloud_storage ├── MANIFEST.in ├── README ├── cloudstorage │ ├── __init__.py │ ├── api_utils.py │ ├── cloudstorage_api.py │ ├── common.py │ ├── errors.py │ ├── rest_api.py │ ├── storage_api.py │ └── test_utils.py ├── distribute_setup.py └── setup.py ├── decorator.py ├── feedgen ├── __init__.py ├── __main__.py ├── entry.py ├── ext │ ├── __init__.py │ ├── base.py │ ├── dc.py │ ├── podcast.py │ └── podcast_entry.py ├── feed.py ├── util.py └── version.py ├── gfm ├── LICENSE ├── __init__.py ├── autolink.py ├── automail.py ├── hidden_hilite.py └── semi_sane_lists.py ├── httplib2 ├── __init__.py ├── cacerts.txt ├── iri2uri.py └── socks.py ├── markdown ├── LICENSE.md ├── __init__.py ├── __main__.py ├── blockparser.py ├── blockprocessors.py ├── etree_loader.py ├── extensions │ ├── __init__.py │ ├── abbr.py │ ├── attr_list.py │ ├── codehilite.py │ ├── def_list.py │ ├── extra.py │ ├── fenced_code.py │ ├── footnotes.py │ ├── headerid.py │ ├── html_tidy.py │ ├── meta.py │ ├── nl2br.py │ ├── rss.py │ ├── sane_lists.py │ ├── smart_strong.py │ ├── tables.py │ ├── toc.py │ └── wikilinks.py ├── inlinepatterns.py ├── odict.py ├── postprocessors.py ├── preprocessors.py ├── serializers.py ├── treeprocessors.py └── util.py ├── mdx_gfm ├── LICENSE └── __init__.py ├── mdx_partial_gfm ├── LICENSE └── __init__.py ├── oauth2client ├── __init__.py ├── anyjson.py ├── appengine.py ├── client.py ├── clientsecrets.py ├── crypt.py ├── django_orm.py ├── file.py ├── gce.py ├── keyring_storage.py ├── locked_file.py ├── multistore_file.py ├── old_run.py ├── tools.py ├── util.py └── xsrfutil.py ├── pygments ├── LICENSE ├── __init__.py ├── cmdline.py ├── console.py ├── filter.py ├── filters │ └── __init__.py ├── formatter.py ├── formatters │ ├── __init__.py │ ├── _mapping.py │ ├── bbcode.py │ ├── html.py │ ├── img.py │ ├── latex.py │ ├── other.py │ ├── rtf.py │ ├── svg.py │ ├── terminal.py │ └── terminal256.py ├── lexer.py ├── lexers │ ├── __init__.py │ ├── _asybuiltins.py │ ├── _clbuiltins.py │ ├── _luabuiltins.py │ ├── _mapping.py │ ├── _phpbuiltins.py │ ├── _postgres_builtins.py │ ├── _scilab_builtins.py │ ├── _vimbuiltins.py │ ├── agile.py │ ├── asm.py │ ├── compiled.py │ ├── dotnet.py │ ├── functional.py │ ├── hdl.py │ ├── jvm.py │ ├── math.py │ ├── other.py │ ├── parsers.py │ ├── shell.py │ ├── special.py │ ├── sql.py │ ├── templates.py │ ├── text.py │ └── web.py ├── plugin.py ├── scanner.py ├── style.py ├── styles │ ├── __init__.py │ ├── autumn.py │ ├── borland.py │ ├── bw.py │ ├── colorful.py │ ├── default.py │ ├── emacs.py │ ├── friendly.py │ ├── fruity.py │ ├── manni.py │ ├── monokai.py │ ├── murphy.py │ ├── native.py │ ├── pastie.py │ ├── perldoc.py │ ├── rrt.py │ ├── tango.py │ ├── trac.py │ ├── vim.py │ └── vs.py ├── token.py ├── unistring.py └── util.py ├── pystache ├── LICENSE ├── __init__.py ├── commands │ ├── __init__.py │ ├── render.py │ └── test.py ├── common.py ├── context.py ├── defaults.py ├── init.py ├── loader.py ├── locator.py ├── parsed.py ├── parser.py ├── renderengine.py ├── renderer.py ├── specloader.py ├── template_spec.py └── tests │ ├── __init__.py │ ├── benchmark.py │ ├── common.py │ ├── data │ ├── __init__.py │ ├── ascii.mustache │ ├── duplicate.mustache │ ├── locator │ │ ├── __init__.py │ │ └── duplicate.mustache │ ├── non_ascii.mustache │ ├── sample_view.mustache │ ├── say_hello.mustache │ └── views.py │ ├── doctesting.py │ ├── examples │ ├── __init__.py │ ├── comments.mustache │ ├── comments.py │ ├── complex.mustache │ ├── complex.py │ ├── delimiters.mustache │ ├── delimiters.py │ ├── double_section.mustache │ ├── double_section.py │ ├── escaped.mustache │ ├── escaped.py │ ├── extensionless │ ├── inner_partial.mustache │ ├── inner_partial.txt │ ├── inverted.mustache │ ├── inverted.py │ ├── lambdas.mustache │ ├── lambdas.py │ ├── looping_partial.mustache │ ├── nested_context.mustache │ ├── nested_context.py │ ├── partial_in_partial.mustache │ ├── partial_with_lambda.mustache │ ├── partial_with_partial_and_lambda.mustache │ ├── partials_with_lambdas.py │ ├── readme.py │ ├── say_hello.mustache │ ├── simple.mustache │ ├── simple.py │ ├── tagless.mustache │ ├── template_partial.mustache │ ├── template_partial.py │ ├── template_partial.txt │ ├── unescaped.mustache │ ├── unescaped.py │ ├── unicode_input.mustache │ ├── unicode_input.py │ ├── unicode_output.mustache │ └── unicode_output.py │ ├── main.py │ ├── spectesting.py │ ├── test___init__.py │ ├── test_commands.py │ ├── test_context.py │ ├── test_examples.py │ ├── test_loader.py │ ├── test_locator.py │ ├── test_parser.py │ ├── test_pystache.py │ ├── test_renderengine.py │ ├── test_renderer.py │ ├── test_simple.py │ └── test_specloader.py ├── repoze ├── LICENSE.txt ├── __init__.py └── lru │ └── __init__.py ├── routes ├── LICENSE ├── __init__.py ├── base.py ├── mapper.py ├── middleware.py ├── route.py └── util.py ├── uritemplate └── __init__.py └── yaml ├── LICENSE ├── __init__.py ├── composer.py ├── constructor.py ├── cyaml.py ├── dumper.py ├── emitter.py ├── error.py ├── events.py ├── loader.py ├── nodes.py ├── parser.py ├── reader.py ├── representer.py ├── resolver.py ├── scanner.py ├── serializer.py └── tokens.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .sass-cache/ 3 | .DS_Store 4 | .idea 5 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Below is a list of people and organizations that have contributed 2 | # to the Dart project. Names should be added to the list like so: 3 | # 4 | # Name/Organization 5 | 6 | Google Inc. 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "compass" 4 | gem "compass_twitter_bootstrap", "~>2.0.3" 5 | gem "foreman" 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | chunky_png (1.2.9) 5 | compass (0.12.2) 6 | chunky_png (~> 1.2) 7 | fssm (>= 0.2.7) 8 | sass (~> 3.1) 9 | compass_twitter_bootstrap (2.0.3) 10 | compass 11 | dotenv (0.9.0) 12 | foreman (0.63.0) 13 | dotenv (>= 0.7) 14 | thor (>= 0.13.6) 15 | fssm (0.2.10) 16 | sass (3.2.12) 17 | thor (0.18.1) 18 | 19 | PLATFORMS 20 | ruby 21 | 22 | DEPENDENCIES 23 | compass 24 | compass_twitter_bootstrap (~> 2.0.3) 25 | foreman 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This license applies to all parts of pub.dartlang.org that are not 2 | externally maintained libraries. The external maintained libraries 3 | used by pub.dartlang.org are: 4 | 5 | CherryPy - in third_party/cherrypy 6 | Pystache - in third_party/pystache 7 | Routes - in third_party/routes 8 | repoze.lru - in third_party/repoze/lru 9 | decorator - in third_party/decorator.py 10 | PyYaml - in third_party/yaml 11 | Markdown - in third_party/markdown 12 | Pygments - in third_party/pygments 13 | PyGFM - in third_party/gfm, third_party/mdx_gfm, and 14 | third_party/mdx_partial_gfm 15 | 16 | The libraries may have their own licenses; we recommend you read them, 17 | as their terms may differ from the terms below. 18 | 19 | Copyright 2012, the Dart project authors. All rights reserved. 20 | Redistribution and use in source and binary forms, with or without 21 | modification, are permitted provided that the following conditions are 22 | met: 23 | * Redistributions of source code must retain the above copyright 24 | notice, this list of conditions and the following disclaimer. 25 | * Redistributions in binary form must reproduce the above 26 | copyright notice, this list of conditions and the following 27 | disclaimer in the documentation and/or other materials provided 28 | with the distribution. 29 | * Neither the name of Google Inc. nor the names of its 30 | contributors may be used to endorse or promote products derived 31 | from this software without specific prior written permission. 32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 35 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 42 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | compass: bundle exec compass watch css 2 | -------------------------------------------------------------------------------- /app/apiclient: -------------------------------------------------------------------------------- 1 | ../third_party/apiclient/ -------------------------------------------------------------------------------- /app/app.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | application: dartlang-pub 6 | version: 37 7 | runtime: python27 8 | threadsafe: true 9 | api_version: 1 10 | 11 | builtins: 12 | - deferred: on 13 | - remote_api: on 14 | 15 | handlers: 16 | - url: /static 17 | static_dir: static 18 | secure: always 19 | 20 | - url: /(.*\.ico) 21 | static_files: static/\1 22 | expiration: 7d 23 | upload: static/(.*\.ico) 24 | secure: always 25 | 26 | - url: /img/ 27 | static_dir: static/img 28 | secure: always 29 | 30 | - url: /.* 31 | script: pub_dartlang.app 32 | secure: always 33 | 34 | libraries: 35 | - name: pycrypto 36 | version: "2.6" 37 | - name: lxml 38 | version: "latest" 39 | 40 | inbound_services: 41 | - warmup 42 | 43 | # After the migration of performance settings from application-level to 44 | # module-level the following settings are necessary: 45 | instance_class: F4 46 | automatic_scaling: 47 | min_idle_instances: 1 48 | max_idle_instances: 885 49 | max_pending_latency: 2.0s 50 | 51 | -------------------------------------------------------------------------------- /app/appengine_config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import os 6 | import re 7 | 8 | from google.appengine.api import namespace_manager 9 | 10 | _PRODUCTION_DATABASE_VERSIONS = ['preview', 'coming-soon'] 11 | """The versions of pub.dartlang.org that should use the production database. 12 | 13 | In addition to these versions, any version that's just a number will use the 14 | production database.""" 15 | 16 | def namespace_manager_default_namespace_for_request(): 17 | """Choose which namespace to use for a given request. 18 | 19 | The database, task queue, and memcache are all automatically partitioned 20 | based on the current namespace. We use two namespaces: the empty string for 21 | the production environment, and "staging" for the staging environment. 22 | """ 23 | version = os.environ.get('CURRENT_VERSION_ID') 24 | version_name = version.split('.')[0] 25 | if version_name in _PRODUCTION_DATABASE_VERSIONS or \ 26 | re.match(r"^[0-9]+$", version_name): 27 | return "" 28 | return "staging" 29 | -------------------------------------------------------------------------------- /app/cherrypy: -------------------------------------------------------------------------------- 1 | ../third_party/cherrypy -------------------------------------------------------------------------------- /app/cloudstorage: -------------------------------------------------------------------------------- 1 | ../third_party/cloud_storage/cloudstorage -------------------------------------------------------------------------------- /app/dateutil/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Copyright (c) 2003-2010 Gustavo Niemeyer 4 | 5 | This module offers extensions to the standard Python 6 | datetime module. 7 | """ 8 | __author__ = "Tomi Pieviläinen " 9 | __license__ = "Simplified BSD" 10 | __version__ = "2.2" 11 | -------------------------------------------------------------------------------- /app/dateutil/parser.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/dateutil/parser.py -------------------------------------------------------------------------------- /app/dateutil/zoneinfo/zoneinfo--latest.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/dateutil/zoneinfo/zoneinfo--latest.tar.gz -------------------------------------------------------------------------------- /app/decorator.py: -------------------------------------------------------------------------------- 1 | ../third_party/decorator.py -------------------------------------------------------------------------------- /app/feedgen: -------------------------------------------------------------------------------- 1 | ../third_party/feedgen -------------------------------------------------------------------------------- /app/gfm: -------------------------------------------------------------------------------- 1 | ../third_party/gfm -------------------------------------------------------------------------------- /app/handlers/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import package_uploaders 6 | import package_versions 7 | import packages 8 | import root 9 | 10 | PackageUploaders = package_uploaders.PackageUploaders 11 | PackageVersions = package_versions.PackageVersions 12 | Packages = packages.Packages 13 | Root = root.Root 14 | -------------------------------------------------------------------------------- /app/handlers/api/package_uploaders.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from google.appengine.api import oauth 6 | from google.appengine.api import users 7 | 8 | import handlers 9 | import models 10 | 11 | class PackageUploaders(object): 12 | """The handler for /api/packages/*/uploaders/*.""" 13 | 14 | @handlers.api(1) 15 | @handlers.requires_uploader 16 | @models.transactional 17 | def create(self, package_id, email): 18 | """Add a new uploader for this package. 19 | 20 | Only other uploaders may add new uploaders.""" 21 | 22 | package = handlers.request().package 23 | if package.has_uploader_email(email): 24 | handlers.http_error( 25 | 400, "User '%s' is already an uploader for package '%s'." % 26 | (email, package.name)) 27 | 28 | package.uploaderEmails.append(email) 29 | package.put() 30 | package.invalidate_cache() 31 | return handlers.json_success( 32 | "'%s' added as an uploader for package '%s'." % 33 | (email, package.name)) 34 | 35 | @handlers.api(1) 36 | @handlers.requires_uploader 37 | @models.transactional 38 | def delete(self, package_id, id, format=None): 39 | """Delete one of this package's uploaders. 40 | 41 | Only uploaders may delete uploaders. If only one uploader remains, that 42 | uploader may not be deleted until a new one is added. 43 | """ 44 | 45 | # TODO: WHAT IS THIS `format` THING ? 46 | if format: id = id + '.' + format 47 | 48 | package = handlers.request().package 49 | email = id 50 | if not package.has_uploader_email(email): 51 | handlers.http_error( 52 | 400, "'%s' isn't an uploader for package '%s'." % 53 | (email, package.name)) 54 | 55 | if len(package.uploaderEmails) == 1: 56 | handlers.http_error( 57 | 400, ("Package '%s' only has one uploader, so that uploader " + 58 | "can't be removed.") % package.name) 59 | 60 | email_to_delete = email.lower() 61 | package.uploaderEmails = [email for email in package.uploaderEmails 62 | if email.lower() != email_to_delete] 63 | package.put() 64 | package.invalidate_cache() 65 | return handlers.json_success( 66 | "'%s' is no longer an uploader for package '%s'." % 67 | (id, package.name)) 68 | 69 | -------------------------------------------------------------------------------- /app/handlers/api/packages.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import json 6 | 7 | import cherrypy 8 | from google.appengine.api import users 9 | 10 | import handlers 11 | from handlers.pager import QueryPager 12 | from models.package import Package 13 | 14 | class Packages(object): 15 | """The handler for /api/packages/*.""" 16 | 17 | @handlers.api(2) 18 | def index(self, page=1): 19 | """Retrieve a paginated list of uploaded packages. 20 | 21 | Arguments: 22 | page: The page of packages to get. Each page contains 50 packages. 23 | """ 24 | pager = QueryPager(int(page), "/api/packages?page=%d", 25 | Package.all().order('-updated'), 26 | per_page=100) 27 | return json.dumps({ 28 | "packages": [package.as_dict() for package in pager.get_items()], 29 | "prev_url": pager.prev_url, 30 | "next_url": pager.next_url, 31 | "pages": pager.page_count 32 | }) 33 | 34 | @handlers.api(2) 35 | def show(self, id): 36 | """Retrieve the page describing a specific package.""" 37 | return handlers.request().package.as_json() 38 | -------------------------------------------------------------------------------- /app/handlers/api/root.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import json 6 | 7 | import cherrypy 8 | 9 | import handlers 10 | 11 | class Root(object): 12 | """The handler for /api/*.""" 13 | 14 | @handlers.api(2) 15 | def index(self): 16 | """Retrieves the index of all entrypoints to the API.""" 17 | return json.dumps({ 18 | "packages_url": handlers.request().url( 19 | controller="api.packages", action="index") + "{/package}" 20 | }) 21 | -------------------------------------------------------------------------------- /app/handlers/doc.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import cherrypy 6 | 7 | import handlers 8 | 9 | _REDIRECTS = { 10 | # /doc/ goes to "Getting started". 11 | '': 'get-started.html', 12 | 13 | # Redirect from the old names for the commands. 14 | 'pub-install.html': 'cmd/pub-get.html', 15 | 'pub-update.html': 'cmd/pub-upgrade.html', 16 | 17 | # Most of the moved docs have the same name. 18 | 'get-started.html': 'get-started.html', 19 | 'dependencies.html': 'dependencies.html', 20 | 'pubspec.html': 'pubspec.html', 21 | 'package-layout.html': 'package-layout.html', 22 | 'assets-and-transformers.html': 'assets-and-transformers.html', 23 | 'faq.html': 'faq.html', 24 | 'glossary.html': 'glossary.html', 25 | 'versioning.html': 'versioning.html', 26 | 27 | # The command references were moved under "cmd". 28 | 'pub-build.html': 'cmd/pub-build.html', 29 | 'pub-cache.html': 'cmd/pub-cache.html', 30 | 'pub-get.html': 'cmd/pub-get.html', 31 | 'pub-lish.html': 'cmd/pub-lish.html', 32 | 'pub-upgrade.html': 'cmd/pub-upgrade.html', 33 | 'pub-serve.html': 'cmd/pub-serve.html' 34 | } 35 | 36 | class Doc(object): 37 | """The handler for /doc/*.""" 38 | 39 | def index(self): 40 | raise cherrypy.HTTPRedirect( 41 | 'https://www.dartlang.org/tools/pub/get-started.html') 42 | 43 | def show(self, path): 44 | """Redirect to a documentation page on dartlang.org. 45 | 46 | Pub used to host its own docs, but no longer does. These redirects 47 | allow existing links to the docs to map to the new ones. 48 | """ 49 | 50 | # Only redirect the known paths. 51 | try: 52 | redirect = _REDIRECTS[path] 53 | raise cherrypy.HTTPRedirect( 54 | 'https://www.dartlang.org/tools/pub/' + redirect) 55 | except KeyError: 56 | handlers.http_error(404) 57 | -------------------------------------------------------------------------------- /app/handlers/feed.py: -------------------------------------------------------------------------------- 1 | from feedgen.feed import FeedGenerator 2 | 3 | import uuid 4 | import handlers 5 | from handlers.pager import QueryPager 6 | from models.package import Package 7 | import cherrypy 8 | from datetime import datetime 9 | 10 | XML_BEGIN = '' 11 | 12 | 13 | class Feeds(object): 14 | """Generation of Feeds""" 15 | 16 | @staticmethod 17 | def generate_feed(page=1): 18 | feed = FeedGenerator() 19 | feed.id("https://pub.dartlang.org/feed.atom") 20 | feed.title("Pub Packages for Dart") 21 | feed.link(href="https://pub.dartlang.org/", rel="alternate") 22 | feed.link(href="https://pub.dartlang.org/feed.atom", rel="self") 23 | feed.description("Last Updated Packages") 24 | feed.author({"name": "Dart Team"}) 25 | i = 1 26 | pager = QueryPager(int(page), "/feed.atom?page=%d", 27 | Package.all().order('-updated'), 28 | per_page=10) 29 | for item in pager.get_items(): 30 | i += 1 31 | entry = feed.add_entry() 32 | for author in item.latest_version.pubspec.authors: 33 | entry.author({"name": author[0]}) 34 | entry.title("v" + item.latest_version.pubspec.get("version") +\ 35 | " of " + item.name) 36 | entry.link(link={"href": "https://pub.dartlang.org/packages/" +\ 37 | item.name, "rel": "alternate", "title": item.name}) 38 | entry.id(uuid.uuid5(uuid.NAMESPACE_URL, 39 | ("https://pub.dartlang.org/packages/" + item.name + "#" +\ 40 | item.latest_version.pubspec.get("version")).encode('utf-8')).urn) 41 | entry.description( 42 | item.latest_version.pubspec 43 | .get("description", "Not Available")) 44 | readme = item.latest_version.readme_obj 45 | if readme is not None: 46 | entry.content(readme.render(), type='html') 47 | else: 48 | entry.content("

No README Found

", type='html') 49 | return feed 50 | 51 | def atom(self, page=1): 52 | cherrypy.response.headers['Content-Type'] = "application/atom+xml" 53 | return XML_BEGIN + "\n" +\ 54 | self.generate_feed(page=page).atom_str(pretty=True) 55 | -------------------------------------------------------------------------------- /app/handlers/private_keys.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import cherrypy 6 | 7 | from google.appengine.api import users 8 | 9 | import handlers 10 | from models.private_key import PrivateKey 11 | 12 | class PrivateKeys(object): 13 | """The handler for /private-keys/*. 14 | 15 | The private keys should only need to be set once, but it's still useful to 16 | have a nice interface for doing so. This is that interface. 17 | """ 18 | 19 | @handlers.handle_validation_errors 20 | def create(self, oauth_key, api_key): 21 | """Set the private keys.""" 22 | if not users.is_current_user_admin(): 23 | handlers.http_error(403, "Only admins may set the private keys.") 24 | PrivateKey.set_oauth(oauth_key) 25 | PrivateKey.set_api(api_key) 26 | handlers.flash("Private keys set successfully.") 27 | raise cherrypy.HTTPRedirect("/admin#tab-private-keys") 28 | -------------------------------------------------------------------------------- /app/handlers/root.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import os 6 | 7 | from google.appengine.api import users 8 | 9 | from handlers import cloud_storage 10 | from models.package_version import PackageVersion 11 | from models.private_key import PrivateKey 12 | import handlers 13 | import cherrypy 14 | from models.package import Package 15 | 16 | class Root(object): 17 | """The handler for /*.""" 18 | 19 | def index(self): 20 | """Retrieves the front page of the package server.""" 21 | packages = Package.all().order('-updated').fetch(5) 22 | return handlers.render('index', recent_packages=packages) 23 | 24 | def authorized(self): 25 | """Retrieves the client authorization landing page.""" 26 | return handlers.render( 27 | 'authorized', layout={'title': 'Pub Authorized Successfully'}) 28 | 29 | def site_map(self): 30 | """Retrieves a map of the site.""" 31 | return handlers.render('site_map', layout={'title': 'Site Map'}) 32 | 33 | def admin(self): 34 | """Retrieve a page for performing administrative tasks.""" 35 | 36 | if not users.get_current_user(): 37 | raise cherrypy.HTTPRedirect(users.create_login_url(cherrypy.url())) 38 | elif not users.is_current_user_admin(): 39 | raise handlers.http_error(403) 40 | 41 | reload_status = PackageVersion.get_reload_status() 42 | if reload_status is not None: 43 | reload_status['percentage'] = '%d%%' % ( 44 | 100.0 * reload_status['count'] / reload_status['total']) 45 | 46 | return handlers.render('admin', 47 | reload_status=reload_status, 48 | private_keys_set=PrivateKey.get_oauth() is not None, 49 | production=handlers.is_production(), 50 | layout={'title': 'Admin Console'}) 51 | 52 | def serve(self, filename): 53 | """Serves a cloud storage file for the development server.""" 54 | 55 | if handlers.is_production(): return handlers.http_error(404) 56 | 57 | cherrypy.response.headers['Content-Type'] = 'application/octet-stream' 58 | cherrypy.response.headers['Content-Disposition'] = \ 59 | 'attachment; filename=%s' % os.path.basename(filename) 60 | 61 | try: 62 | with cloud_storage.open(filename) as f: return f.read() 63 | except KeyError, ExistenceError: 64 | handlers.http_error(404) 65 | -------------------------------------------------------------------------------- /app/httplib2: -------------------------------------------------------------------------------- 1 | ../third_party/httplib2/ -------------------------------------------------------------------------------- /app/index.yaml: -------------------------------------------------------------------------------- 1 | indexes: 2 | 3 | # AUTOGENERATED 4 | 5 | # This index.yaml is automatically updated whenever the dev_appserver 6 | # detects that a new type of query is run. If you want to manage the 7 | # index.yaml file manually, remove the above marker line (the line 8 | # saying "# AUTOGENERATED"). If you want to manage some indexes 9 | # manually, move them above the marker line. The index.yaml file is 10 | # automatically uploaded to the admin console when you next deploy 11 | # your application using appcfg.py. 12 | 13 | - kind: PackageVersion 14 | properties: 15 | - name: package 16 | - name: created 17 | direction: desc 18 | 19 | - kind: PackageVersion 20 | properties: 21 | - name: package 22 | - name: sort_order 23 | 24 | - kind: PackageVersion 25 | properties: 26 | - name: package 27 | - name: sort_order 28 | direction: desc 29 | -------------------------------------------------------------------------------- /app/markdown: -------------------------------------------------------------------------------- 1 | ../third_party/markdown -------------------------------------------------------------------------------- /app/mdx_gfm: -------------------------------------------------------------------------------- 1 | ../third_party/mdx_gfm -------------------------------------------------------------------------------- /app/mdx_partial_gfm: -------------------------------------------------------------------------------- 1 | ../third_party/mdx_partial_gfm -------------------------------------------------------------------------------- /app/models/properties.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from google.appengine.ext import db 6 | import json 7 | import pickle 8 | 9 | from pubspec import Pubspec 10 | from readme import Readme 11 | from semantic_version import SemanticVersion 12 | 13 | class DocumentProperty(db.Property): 14 | """A property that stores a JSON-encodable document.""" 15 | 16 | data_type = dict 17 | 18 | def get_value_for_datastore(self, model_instance): 19 | """Dump the document to JSON.""" 20 | value = super(DocumentProperty, self) \ 21 | .get_value_for_datastore(model_instance) 22 | return json.dumps(value) 23 | 24 | def make_value_from_datastore(self, value): 25 | """Load the document from JSON.""" 26 | if value is None: 27 | return None 28 | return json.loads(value) 29 | 30 | class PubspecProperty(DocumentProperty): 31 | """A property that stores a parsed Pubspec.""" 32 | 33 | data_type = Pubspec 34 | 35 | def make_value_from_datastore(self, value): 36 | """Load the pubspec from JSON.""" 37 | contents = super(PubspecProperty, self).make_value_from_datastore(value) 38 | return Pubspec(contents) 39 | 40 | class PickledProperty(db.Property): 41 | """A property that stores a picklable object.""" 42 | 43 | def get_value_for_datastore(self, model_instance): 44 | """Pickle the document.""" 45 | value = super(PickledProperty, self) \ 46 | .get_value_for_datastore(model_instance) 47 | return db.Blob(pickle.dumps(value, 2)) 48 | 49 | def make_value_from_datastore(self, value): 50 | """Load the document from JSON.""" 51 | if value is None: 52 | return None 53 | return pickle.loads(value) 54 | 55 | class ReadmeProperty(PickledProperty): 56 | """A property that stores a README file.""" 57 | 58 | data_type = Readme 59 | 60 | class VersionProperty(db.Property): 61 | """A property that stores a semantic version.""" 62 | 63 | data_type = SemanticVersion 64 | 65 | def get_value_for_datastore(self, model_instance): 66 | value = super(VersionProperty, self) \ 67 | .get_value_for_datastore(model_instance) 68 | return str(value) 69 | 70 | def make_value_from_datastore(self, value): 71 | if value is None: 72 | return None 73 | return SemanticVersion(value) 74 | -------------------------------------------------------------------------------- /app/models/readme.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import cgi 6 | import os 7 | import re 8 | 9 | import markdown 10 | 11 | class Readme(object): 12 | """A README file with associated format information.""" 13 | 14 | class Format(object): 15 | """An enum of possible README formats.""" 16 | TEXT, MARKDOWN = range(2) 17 | 18 | def __init__(self, text, filename): 19 | self.text = text 20 | self.filename = filename 21 | 22 | @classmethod 23 | def from_archive(cls, tar, name="README"): 24 | """Extract and return the README from a package archive. 25 | 26 | Return None if no README could be found. 27 | 28 | Arguments: 29 | tar: A TarFile object. 30 | name: Case-insensitive name for the README file; defaults to `README`. 31 | """ 32 | 33 | # If there are multiple READMEs, choose the one with the fewest 34 | # extensions. This handles the case where there are multiple READMEs in 35 | # different languages named e.g. "README.md" vs "README.jp.md". 36 | readmes = [n for n in tar.getnames() 37 | if os.path.dirname(n) == '' 38 | and re.match('^{0}($|\.)'.format(name), n, re.IGNORECASE)] 39 | if len(readmes) == 0: return None 40 | 41 | filename = min(readmes, key=lambda(n): (n.count('.'), n)) 42 | text = unicode(tar.extractfile(filename).read(), 43 | encoding='utf-8', errors='replace') 44 | return Readme(text, filename) 45 | 46 | @property 47 | def format(self): 48 | """Returns the format of the README as a value of Format.""" 49 | return { 50 | ".md": Readme.Format.MARKDOWN, 51 | ".markdown": Readme.Format.MARKDOWN, 52 | ".mdown": Readme.Format.MARKDOWN, 53 | }.get(os.path.splitext(self.filename)[1].lower(), Readme.Format.TEXT) 54 | 55 | def render(self): 56 | """Renders the README to HTML.""" 57 | return { 58 | Readme.Format.MARKDOWN: _render_markdown, 59 | Readme.Format.TEXT: _render_text, 60 | }[self.format](self.text) 61 | 62 | def _render_markdown(text): 63 | return markdown.markdown( 64 | text, output_format="html5", safe_mode='escape', 65 | extensions=['partial_gfm']) 66 | 67 | def _render_text(text): 68 | return '
%s
' % cgi.escape(text) 69 | -------------------------------------------------------------------------------- /app/oauth2client: -------------------------------------------------------------------------------- 1 | ../third_party/oauth2client/ -------------------------------------------------------------------------------- /app/pygments: -------------------------------------------------------------------------------- 1 | ../third_party/pygments -------------------------------------------------------------------------------- /app/pystache: -------------------------------------------------------------------------------- 1 | ../third_party/pystache -------------------------------------------------------------------------------- /app/repoze: -------------------------------------------------------------------------------- 1 | ../third_party/repoze -------------------------------------------------------------------------------- /app/routes: -------------------------------------------------------------------------------- 1 | ../third_party/routes -------------------------------------------------------------------------------- /app/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/favicon.ico -------------------------------------------------------------------------------- /app/static/img/assets-and-transformers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/img/assets-and-transformers.png -------------------------------------------------------------------------------- /app/static/img/dart-logo-400x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/img/dart-logo-400x400.png -------------------------------------------------------------------------------- /app/static/img/dart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/img/dart.png -------------------------------------------------------------------------------- /app/static/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /app/static/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /app/static/img/input-and-output-assets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/app/static/img/input-and-output-assets.png -------------------------------------------------------------------------------- /app/static/js/script.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | * for details. All rights reserved. Use of this source code is governed by a 3 | * BSD-style license that can be found in the LICENSE file. */ 4 | 5 | $(function() { 6 | $("article").find("h2, h3, h4").each(function() { 7 | $(this).append($('')); 8 | }); 9 | 10 | // Allow the anchor to specify which tab of a tabbed control is shown. 11 | if (window.location.hash !== "") { 12 | $('a[href="' + window.location.hash + '"][data-toggle="tab"]').tab('show'); 13 | } 14 | 15 | var reload = $(".admin .reload"); 16 | if (reload.length != 0) { 17 | var reloadInterval = setInterval(function() { 18 | $.ajax({ 19 | url: "/packages/versions/reload.json", 20 | dataType: "json" 21 | }).done(function(data) { 22 | if (data['done']) { 23 | clearInterval(reloadInterval); 24 | reload.find(".progress .bar").css("width", "100%"); 25 | reload.find(".progress").removeClass("active"); 26 | reload.find("h3").text("All packages reloaded") 27 | return; 28 | } 29 | 30 | reload.find(".count").text(data["count"]); 31 | reload.find(".total").text(data["total"]); 32 | var percentage = (100 * data["count"]/data["total"]) + '%'; 33 | reload.find(".progress .bar").css("width", percentage); 34 | }); 35 | }, 1000); 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /app/uritemplate: -------------------------------------------------------------------------------- 1 | ../third_party/uritemplate/ -------------------------------------------------------------------------------- /app/views/admin.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Admin Console

6 | 7 |
8 | 14 |
15 |
16 | {{#reload_status}} 17 |
18 |

19 | Reloading Packages: 20 | {{count}}/{{total}} 21 |

22 | 23 |
24 |
25 |
26 |
27 | {{/reload_status}} 28 | 29 |
30 | 31 |
32 |
33 |
34 | {{#private_keys_set}} 35 |

36 | Note: the private keys have already been set. 37 |

38 | {{/private_keys_set}} 39 | {{^private_keys_set}} 40 | {{^production}} 41 |

42 | In development, the private keys may be any string. 43 |

44 | {{/production}} 45 | {{/private_keys_set}} 46 | 47 |
48 |

OAuth2 Key

49 | 50 |

Google API Key

51 | 52 | 53 |
54 |
55 |
56 |
57 | -------------------------------------------------------------------------------- /app/views/authorized.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Pub Authorized Successfully

6 | 7 |

8 | The pub client has been successfully authorized. You may now 9 | use it to upload packages and perform other tasks. 10 |

11 | -------------------------------------------------------------------------------- /app/views/error.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Error {{status}}

6 |

{{message}}

7 | {{#traceback}} 8 |
{{traceback}}
9 | {{/traceback}} -------------------------------------------------------------------------------- /app/views/index.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |
6 |

Welcome to pub.dartlang.org!

7 |

8 | This is your friendly repository of packages of software for the 9 | Dart programming language. Explore 10 | packages here and install them using pub, the package 11 | manager for Dart. 12 |

13 | 15 | Get started 16 | 17 |
18 |

Recently updated packages

19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {{#recent_packages}} 30 | 31 | 32 | 33 | 34 | 35 | 36 | {{/recent_packages}} 37 | 38 | 39 | 40 | 41 | 42 | 43 |
PackageVersionDescriptionUpdated
{{name}}{{latest_version.version}}{{#description}}{{ellipsized_description}}{{/description}}{{short_updated}}
More packages...
44 | -------------------------------------------------------------------------------- /app/views/packages/index.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Packages

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {{#packages}} 17 | 18 | 19 | 20 | 21 | 22 | 23 | {{/packages}} 24 | 25 |
PackageDescriptionAuthor(s)Updated
{{name}}{{#description}}{{ellipsized_description}}{{/description}}{{& authors_html}}{{short_updated}}
26 | 27 | {{{pagination}}} 28 | -------------------------------------------------------------------------------- /app/views/packages/versions/index.mustache: -------------------------------------------------------------------------------- 1 |

All versions of {{package.name}}

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{#versions}} 13 | 14 | 15 | 16 | 24 | 32 | 33 | {{/versions}} 34 | 35 |
VersionUploadedDocumentationArchive
{{version}}{{short_created}} 17 | 19 | 20 | Go to the documentation of {{package.name}} {{version}} 21 | 22 | 23 | 25 | 27 | 28 | Download {{package.name}} {{version}} archive 29 | 30 | 31 |
-------------------------------------------------------------------------------- /app/views/pagination.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 | 16 | -------------------------------------------------------------------------------- /app/views/private_keys/new.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Set the private key

6 | 7 | {{#already_set}} 8 |

Note: the private key has already been set.

9 | {{/already_set}} 10 | 11 | {{^production}} 12 |

In development, the private key may be any string.

13 | {{/production}} 14 | 15 |
16 | 17 | 18 |
19 | -------------------------------------------------------------------------------- /app/views/search.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Search Results for “{{query}}”

6 | {{#hasResults}} 7 | 8 | 9 | {{/hasResults}} 10 | {{#results}} 11 | 12 | 17 | 18 | {{/results}} 19 | {{#hasResults}} 20 | 21 |
13 |

{{name}} {{version}}

14 |

{{desc}}

15 |

last updated {{last_uploaded}}

16 |
22 | {{/hasResults}} 23 | {{^hasResults}} 24 |

Search for “{{query}}” did not match any packages.

25 | {{/hasResults}} 26 | 27 | {{{pagination}}} 28 | -------------------------------------------------------------------------------- /app/views/site_map.mustache: -------------------------------------------------------------------------------- 1 | {{! Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | for details. All rights reserved. Use of this source code is governed by a 3 | BSD-style license that can be found in the LICENSE file. }} 4 | 5 |

Site Map

6 | 7 | 10 | -------------------------------------------------------------------------------- /app/yaml: -------------------------------------------------------------------------------- 1 | ../third_party/yaml -------------------------------------------------------------------------------- /codereview.settings: -------------------------------------------------------------------------------- 1 | CODE_REVIEW_SERVER: https://chromiumcodereview.appspot.com/ 2 | VIEW_VC: https://github.com/dart-lang/pub-dartlang/commit/ 3 | CC_LIST: 4 | -------------------------------------------------------------------------------- /css/config.rb: -------------------------------------------------------------------------------- 1 | require 'compass_twitter_bootstrap' 2 | 3 | http_path = "/" 4 | css_dir = "../app/static" 5 | sass_dir = "sass" 6 | images_dir = "images" 7 | javascripts_dir = "javascripts" 8 | 9 | # Don't include comments with random user-specific file paths in them. 10 | line_comments = false 11 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 | # for details. All rights reserved. Use of this source code is governed by a 4 | # BSD-style license that can be found in the LICENSE file. 5 | 6 | """The entrypoint for running tests. 7 | 8 | If the App Engine dev_appserver.py is on $PATH, this can be run without any 9 | arguments. Otherwise, it should be passed a single argument: the path to the App 10 | Engine SDK. 11 | """ 12 | 13 | import optparse 14 | import os 15 | import sys 16 | import subprocess 17 | 18 | import unittest 19 | 20 | USAGE = """%prog [SDK_PATH] 21 | Run unit tests. 22 | 23 | SDK_PATH Path to the SDK installation. 24 | Auto-detected if dev_appserver.py is on $PATH.""" 25 | 26 | parser = optparse.OptionParser(USAGE) 27 | parser.add_option('-n', '--name', help='the name of the test to run', 28 | metavar='NAME') 29 | 30 | options, args = parser.parse_args() 31 | sdk_path = None 32 | if len(args) > 1: 33 | print 'Error: 0 or 1 arguments required.' 34 | parser.print_help() 35 | sys.exit(1) 36 | elif len(args) == 1: 37 | sdk_path = args[0] 38 | else: 39 | process = subprocess.Popen(["which", "dev_appserver.py"], 40 | stdout=subprocess.PIPE) 41 | stdout = process.communicate()[0] 42 | if process.returncode > 0: 43 | print('Error: could not find SDK path.') 44 | parser.print_help() 45 | sys.exit(1) 46 | sdk_path = os.path.dirname(stdout.strip()) 47 | 48 | sys.path.append(sdk_path) 49 | import dev_appserver 50 | dev_appserver.fix_sys_path() 51 | sys.path.append(os.path.join(os.path.dirname(__file__), 'app')) 52 | 53 | test_path = os.path.join(os.path.dirname(__file__), 'test') 54 | loader = unittest.loader.TestLoader() 55 | if options.name: loader.testMethodPrefix = options.name 56 | unittest.TextTestRunner(verbosity = 2).run(loader.discover(test_path)) 57 | -------------------------------------------------------------------------------- /test/test_handlers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/test/test_handlers/__init__.py -------------------------------------------------------------------------------- /test/test_handlers/api/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/test_handlers/api/test_version_negotiation.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from testcase import TestCase 6 | 7 | class VersionNegotiationTest(TestCase): 8 | # TODO(nweiz): when we have any actions that change behavior based on the 9 | # API version, test that. Also test that the latest version is the default. 10 | 11 | def test_rejects_too_low_version(self): 12 | self.testapp.get( 13 | '/api/packages', 14 | headers={'Accept': 'application/vnd.pub.v1+json'}, 15 | status=406) 16 | 17 | def test_rejects_too_high_version(self): 18 | self.testapp.get( 19 | '/api/packages', 20 | headers={'Accept': 'application/vnd.pub.v3+json'}, 21 | status=406) 22 | 23 | def test_rejects_malformed_version(self): 24 | self.testapp.get( 25 | '/api/packages', 26 | headers={'Accept': 'application/vnd.pub.asdf+json'}, 27 | status=406) 28 | 29 | def test_rejects_malformed_format(self): 30 | self.testapp.get( 31 | '/api/packages', 32 | headers={'Accept': 'application/vnd.pub.v2+yaml'}, 33 | status=406) 34 | -------------------------------------------------------------------------------- /test/test_handlers/test_error.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from testcase import TestCase, mock_not_on_dev_server 6 | 7 | from models.package import Package 8 | 9 | class ErrorTest(TestCase): 10 | def test_error_traceback_shown_on_dev_server(self): 11 | self.be_normal_user() 12 | response = self.testapp.get('/not/real/here/comes/a/404', status=404) 13 | self.assert_error_page(response) 14 | self.assertIsNotNone(self.html(response).find('pre', 'traceback')) 15 | 16 | @mock_not_on_dev_server 17 | def test_error_traceback_shown_to_admin(self): 18 | self.be_admin_user() 19 | response = self.testapp.get('/not/real/here/comes/a/404', status=404) 20 | self.assert_error_page(response) 21 | self.assertIsNotNone(self.html(response).find('pre', 'traceback')) 22 | 23 | @mock_not_on_dev_server 24 | def test_error_traceback_not_shown(self): 25 | self.be_normal_user() 26 | response = self.testapp.get('/not/real/here/comes/a/404', status=404) 27 | self.assert_error_page(response) 28 | self.assertIsNone(self.html(response).find('pre', 'traceback')) 29 | -------------------------------------------------------------------------------- /test/test_handlers/test_package_uploaders.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from models.package import Package 6 | from testcase import TestCase 7 | 8 | class PackageUploadersTest(TestCase): 9 | def setUp(self): 10 | super(PackageUploadersTest, self).setUp() 11 | self.package = Package.new( 12 | name='test-package', 13 | uploaders=[self.normal_user('uploader1'), 14 | self.normal_user('uploader2')]) 15 | self.package.put() 16 | 17 | def test_uploader_creates_new_uploader(self): 18 | self.be_normal_oauth_user('uploader1') 19 | response = self.testapp.post('/packages/test-package/uploaders.json', 20 | {'email': self.normal_user().email()}) 21 | self.assert_json_success(response) 22 | 23 | package = Package.get_by_key_name('test-package') 24 | self.assertEquals(package.uploaders, [ 25 | self.normal_user('uploader1'), 26 | self.normal_user('uploader2'), 27 | self.normal_user() 28 | ]) 29 | 30 | def test_uploader_deletes_uploader(self): 31 | self.be_normal_oauth_user('uploader1') 32 | response = self.testapp.delete( 33 | '/packages/test-package/uploaders/%s.json' % 34 | self.normal_user('uploader1').email()) 35 | self.assert_json_success(response) 36 | 37 | package = Package.get_by_key_name('test-package') 38 | self.assertEquals( 39 | package.uploaders, [self.normal_user('uploader2')]) 40 | -------------------------------------------------------------------------------- /test/test_handlers/test_private_keys.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from testcase import TestCase 6 | 7 | from models.private_key import PrivateKey 8 | 9 | class PrivateKeysTest(TestCase): 10 | def test_create_requires_admin(self): 11 | self.be_normal_user() 12 | 13 | response = self.testapp.post( 14 | '/private-keys', params='oauth_key=oauth&api_key=api', status=403) 15 | self.assert_error_page(response) 16 | 17 | def test_admin_creates_keys(self): 18 | self.be_admin_user() 19 | 20 | get_response = self.testapp.get('/admin') 21 | self.assertEqual(get_response.status_int, 200) 22 | form = get_response.forms["private-key"] 23 | self.assertEqual(form.method, 'POST') 24 | 25 | form['oauth_key'] = 'oauth' 26 | form['api_key'] = 'api' 27 | post_response = form.submit() 28 | 29 | self.assertEqual(post_response.status_int, 302) 30 | self.assertEqual(post_response.headers['Location'], 31 | 'http://localhost:80/admin#tab-private-keys') 32 | self.assertEqual(PrivateKey.get_oauth(), 'oauth') 33 | self.assertEqual(PrivateKey.get_api(), 'api') 34 | -------------------------------------------------------------------------------- /test/test_handlers/test_root.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from testcase import TestCase 6 | 7 | import handlers 8 | from models.package import Package 9 | from models.package_version import PackageVersion 10 | 11 | class RootTest(TestCase): 12 | def test_in_production_is_false_in_tests(self): 13 | # A little sanity check to make sure the tests don't run against 14 | # production. 15 | self.assertFalse(handlers.is_production()) 16 | 17 | def test_index_lists_recent_packages_in_update_order(self): 18 | self.be_admin_user() 19 | 20 | packages = [ 21 | 'armadillo', 'bat', 'crocodile', 'dragon', 'elephant', 'frog', 22 | 'gorilla', 'headcrab' 23 | ] 24 | 25 | for package in packages: 26 | self.create_package(package, '1.0.0') 27 | 28 | # Update a package so the update times are different from create times. 29 | self.set_latest_version('bat', '1.0.1') 30 | 31 | # Only the five most recent packages should be listed 32 | self.assert_list_in_html('/', 'tbody tr th', 33 | ['bat', 'headcrab', 'gorilla', 'frog', 'elephant']) 34 | 35 | def test_admin_requires_login(self): 36 | response = self.testapp.get('/admin') 37 | self.assert_requires_login(response) 38 | 39 | def test_admin_requires_admin(self): 40 | self.be_normal_user() 41 | response = self.testapp.get('/admin', status=403) 42 | self.assert_error_page(response) 43 | -------------------------------------------------------------------------------- /test/test_models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/test/test_models/__init__.py -------------------------------------------------------------------------------- /test/test_models/test_models.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from testcase import TestCase 6 | import models 7 | 8 | class ModelTest(TestCase): 9 | def test_ellipsize(self): 10 | self.assertEquals("foo bar", models.ellipsize("foo bar", 7)) 11 | self.assertEquals("foo...", models.ellipsize("foo bar baz", 7)) 12 | self.assertEquals("foobarb...", models.ellipsize("foobarbaz", 7)) 13 | -------------------------------------------------------------------------------- /test/test_models/test_package.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from testcase import TestCase 6 | from models.package import Package 7 | 8 | class PackageTest(TestCase): 9 | def test_exists(self): 10 | Package.new(name='test-package', uploaders=[self.admin_user()]).put() 11 | 12 | self.assertTrue(Package.exists('test-package')) 13 | self.assertFalse(Package.exists('other-package')) 14 | 15 | def test_has_version(self): 16 | package = Package.new(name='test-package', 17 | uploaders=[self.admin_user()]) 18 | package.put() 19 | self.package_version(package, '1.2.3').put() 20 | 21 | self.assertTrue(package.has_version('1.2.3')) 22 | self.assertFalse(package.has_version('1.2.4')) 23 | 24 | def test_description(self): 25 | package = Package.new(name='test-package', 26 | uploaders=[self.admin_user()]) 27 | package.put() 28 | 29 | def get_description(): 30 | return Package.get_by_key_name(package.name).description 31 | 32 | def set_latest_version(version, **additional_pubspec_fields): 33 | version = self.package_version( 34 | package, version, **additional_pubspec_fields) 35 | package.latest_version = version 36 | version.put() 37 | package.put() 38 | 39 | self.assertIsNone(get_description()) 40 | 41 | set_latest_version('1.2.3') 42 | self.assertIsNone(get_description()) 43 | 44 | set_latest_version('1.2.4', description='some package') 45 | self.assertEquals('some package', get_description()) 46 | -------------------------------------------------------------------------------- /test/test_models/test_package_version.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from cStringIO import StringIO 6 | 7 | from testcase import TestCase 8 | from models.package_version import PackageVersion 9 | 10 | class PackageVersionTest(TestCase): 11 | def test_imports_from_archive(self): 12 | pubspec = {'name': 'test-package', 'version': '1.0.0'} 13 | archive = self.tar_package(pubspec, { 14 | 'lib/foo.dart': '', 15 | 'lib/bar/foo.dart': '', 16 | 'lib/bar/src/foo.dart': '', 17 | 'lib/zip': '', 18 | 'lib/src/foo.dart': '', 19 | }) 20 | version = PackageVersion.from_archive(StringIO(archive), 21 | uploader=self.admin_user()) 22 | 23 | self.assertEqual(['bar/foo.dart', 'bar/src/foo.dart', 'foo.dart'], 24 | version.libraries) 25 | 26 | def test_loads_readme_from_archive(self): 27 | pubspec = {'name': 'test-package', 'version': '1.0.0'} 28 | archive = self.tar_package(pubspec, { 29 | 'README': 'This is a README.', 30 | }) 31 | version = PackageVersion.from_archive(StringIO(archive), 32 | uploader=self.admin_user()) 33 | self.assertEqual('This is a README.', version.readme.text) 34 | -------------------------------------------------------------------------------- /third_party/apiclient/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2012 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | __version__ = "1.2" 16 | -------------------------------------------------------------------------------- /third_party/cherrypy/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2011, CherryPy Team (team@cherrypy.org) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | * Neither the name of the CherryPy Team nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /third_party/cherrypy/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/third_party/cherrypy/favicon.ico -------------------------------------------------------------------------------- /third_party/cherrypy/lib/__init__.py: -------------------------------------------------------------------------------- 1 | """CherryPy Library""" 2 | 3 | # Deprecated in CherryPy 3.2 -- remove in CherryPy 3.3 4 | from cherrypy.lib.reprconf import unrepr, modules, attributes 5 | 6 | class file_generator(object): 7 | """Yield the given input (a file object) in chunks (default 64k). (Core)""" 8 | 9 | def __init__(self, input, chunkSize=65536): 10 | self.input = input 11 | self.chunkSize = chunkSize 12 | 13 | def __iter__(self): 14 | return self 15 | 16 | def __next__(self): 17 | chunk = self.input.read(self.chunkSize) 18 | if chunk: 19 | return chunk 20 | else: 21 | if hasattr(self.input, 'close'): 22 | self.input.close() 23 | raise StopIteration() 24 | next = __next__ 25 | 26 | def file_generator_limited(fileobj, count, chunk_size=65536): 27 | """Yield the given file object in chunks, stopping after `count` 28 | bytes has been emitted. Default chunk size is 64kB. (Core) 29 | """ 30 | remaining = count 31 | while remaining > 0: 32 | chunk = fileobj.read(min(chunk_size, remaining)) 33 | chunklen = len(chunk) 34 | if chunklen == 0: 35 | return 36 | remaining -= chunklen 37 | yield chunk 38 | 39 | def set_vary_header(response, header_name): 40 | "Add a Vary header to a response" 41 | varies = response.headers.get("Vary", "") 42 | varies = [x.strip() for x in varies.split(",") if x.strip()] 43 | if header_name not in varies: 44 | varies.append(header_name) 45 | response.headers['Vary'] = ", ".join(varies) 46 | -------------------------------------------------------------------------------- /third_party/cherrypy/lib/http.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | warnings.warn('cherrypy.lib.http has been deprecated and will be removed ' 3 | 'in CherryPy 3.3 use cherrypy.lib.httputil instead.', 4 | DeprecationWarning) 5 | 6 | from cherrypy.lib.httputil import * 7 | 8 | -------------------------------------------------------------------------------- /third_party/cherrypy/lib/xmlrpcutil.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import cherrypy 4 | from cherrypy._cpcompat import ntob 5 | 6 | def get_xmlrpclib(): 7 | try: 8 | import xmlrpc.client as x 9 | except ImportError: 10 | import xmlrpclib as x 11 | return x 12 | 13 | def process_body(): 14 | """Return (params, method) from request body.""" 15 | try: 16 | return get_xmlrpclib().loads(cherrypy.request.body.read()) 17 | except Exception: 18 | return ('ERROR PARAMS', ), 'ERRORMETHOD' 19 | 20 | 21 | def patched_path(path): 22 | """Return 'path', doctored for RPC.""" 23 | if not path.endswith('/'): 24 | path += '/' 25 | if path.startswith('/RPC2/'): 26 | # strip the first /rpc2 27 | path = path[5:] 28 | return path 29 | 30 | 31 | def _set_response(body): 32 | # The XML-RPC spec (http://www.xmlrpc.com/spec) says: 33 | # "Unless there's a lower-level error, always return 200 OK." 34 | # Since Python's xmlrpclib interprets a non-200 response 35 | # as a "Protocol Error", we'll just return 200 every time. 36 | response = cherrypy.response 37 | response.status = '200 OK' 38 | response.body = ntob(body, 'utf-8') 39 | response.headers['Content-Type'] = 'text/xml' 40 | response.headers['Content-Length'] = len(body) 41 | 42 | 43 | def respond(body, encoding='utf-8', allow_none=0): 44 | xmlrpclib = get_xmlrpclib() 45 | if not isinstance(body, xmlrpclib.Fault): 46 | body = (body,) 47 | _set_response(xmlrpclib.dumps(body, methodresponse=1, 48 | encoding=encoding, 49 | allow_none=allow_none)) 50 | 51 | def on_error(*args, **kwargs): 52 | body = str(sys.exc_info()[1]) 53 | xmlrpclib = get_xmlrpclib() 54 | _set_response(xmlrpclib.dumps(xmlrpclib.Fault(1, body))) 55 | 56 | -------------------------------------------------------------------------------- /third_party/cherrypy/process/__init__.py: -------------------------------------------------------------------------------- 1 | """Site container for an HTTP server. 2 | 3 | A Web Site Process Bus object is used to connect applications, servers, 4 | and frameworks with site-wide services such as daemonization, process 5 | reload, signal handling, drop privileges, PID file management, logging 6 | for all of these, and many more. 7 | 8 | The 'plugins' module defines a few abstract and concrete services for 9 | use with the bus. Some use tool-specific channels; see the documentation 10 | for each class. 11 | """ 12 | 13 | from cherrypy.process.wspbus import bus 14 | from cherrypy.process import plugins, servers 15 | -------------------------------------------------------------------------------- /third_party/cherrypy/scaffold/__init__.py: -------------------------------------------------------------------------------- 1 | """, a CherryPy application. 2 | 3 | Use this as a base for creating new CherryPy applications. When you want 4 | to make a new app, copy and paste this folder to some other location 5 | (maybe site-packages) and rename it to the name of your project, 6 | then tweak as desired. 7 | 8 | Even before any tweaking, this should serve a few demonstration pages. 9 | Change to this directory and run: 10 | 11 | ../cherryd -c site.conf 12 | 13 | """ 14 | 15 | import cherrypy 16 | from cherrypy import tools, url 17 | 18 | import os 19 | local_dir = os.path.join(os.getcwd(), os.path.dirname(__file__)) 20 | 21 | 22 | class Root: 23 | 24 | _cp_config = {'tools.log_tracebacks.on': True, 25 | } 26 | 27 | def index(self): 28 | return """ 29 | Try some other path, 30 | or a default path.
31 | Or, just look at the pretty picture:
32 | 33 | """ % (url("other"), url("else"), 34 | url("files/made_with_cherrypy_small.png")) 35 | index.exposed = True 36 | 37 | def default(self, *args, **kwargs): 38 | return "args: %s kwargs: %s" % (args, kwargs) 39 | default.exposed = True 40 | 41 | def other(self, a=2, b='bananas', c=None): 42 | cherrypy.response.headers['Content-Type'] = 'text/plain' 43 | if c is None: 44 | return "Have %d %s." % (int(a), b) 45 | else: 46 | return "Have %d %s, %s." % (int(a), b, c) 47 | other.exposed = True 48 | 49 | files = cherrypy.tools.staticdir.handler( 50 | section="/files", 51 | dir=os.path.join(local_dir, "static"), 52 | # Ignore .php files, etc. 53 | match=r'\.(css|gif|html?|ico|jpe?g|js|png|swf|xml)$', 54 | ) 55 | 56 | 57 | root = Root() 58 | 59 | # Uncomment the following to use your own favicon instead of CP's default. 60 | #favicon_path = os.path.join(local_dir, "favicon.ico") 61 | #root.favicon_ico = tools.staticfile.handler(filename=favicon_path) 62 | -------------------------------------------------------------------------------- /third_party/cherrypy/scaffold/apache-fcgi.conf: -------------------------------------------------------------------------------- 1 | # Apache2 server conf file for using CherryPy with mod_fcgid. 2 | 3 | # This doesn't have to be "C:/", but it has to be a directory somewhere, and 4 | # MUST match the directory used in the FastCgiExternalServer directive, below. 5 | DocumentRoot "C:/" 6 | 7 | ServerName 127.0.0.1 8 | Listen 80 9 | LoadModule fastcgi_module modules/mod_fastcgi.dll 10 | LoadModule rewrite_module modules/mod_rewrite.so 11 | 12 | Options ExecCGI 13 | SetHandler fastcgi-script 14 | RewriteEngine On 15 | # Send requests for any URI to our fastcgi handler. 16 | RewriteRule ^(.*)$ /fastcgi.pyc [L] 17 | 18 | # The FastCgiExternalServer directive defines filename as an external FastCGI application. 19 | # If filename does not begin with a slash (/) then it is assumed to be relative to the ServerRoot. 20 | # The filename does not have to exist in the local filesystem. URIs that Apache resolves to this 21 | # filename will be handled by this external FastCGI application. 22 | FastCgiExternalServer "C:/fastcgi.pyc" -host 127.0.0.1:8088 -------------------------------------------------------------------------------- /third_party/cherrypy/scaffold/example.conf: -------------------------------------------------------------------------------- 1 | [/] 2 | log.error_file: "error.log" 3 | log.access_file: "access.log" -------------------------------------------------------------------------------- /third_party/cherrypy/scaffold/site.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | # Uncomment this when you're done developing 3 | #environment: "production" 4 | 5 | server.socket_host: "0.0.0.0" 6 | server.socket_port: 8088 7 | 8 | # Uncomment the following lines to run on HTTPS at the same time 9 | #server.2.socket_host: "0.0.0.0" 10 | #server.2.socket_port: 8433 11 | #server.2.ssl_certificate: '../test/test.pem' 12 | #server.2.ssl_private_key: '../test/test.pem' 13 | 14 | tree.myapp: cherrypy.Application(scaffold.root, "/", "example.conf") 15 | -------------------------------------------------------------------------------- /third_party/cherrypy/scaffold/static/made_with_cherrypy_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/third_party/cherrypy/scaffold/static/made_with_cherrypy_small.png -------------------------------------------------------------------------------- /third_party/cherrypy/test/__init__.py: -------------------------------------------------------------------------------- 1 | """Regression test suite for CherryPy. 2 | 3 | Run 'nosetests -s test/' to exercise all tests. 4 | 5 | The '-s' flag instructs nose to output stdout messages, wihch is crucial to 6 | the 'interactive' mode of webtest.py. If you run these tests without the '-s' 7 | flag, don't be surprised if the test seems to hang: it's waiting for your 8 | interactive input. 9 | """ 10 | 11 | import os 12 | import sys 13 | 14 | def newexit(): 15 | os._exit(1) 16 | 17 | def setup(): 18 | # We want to monkey patch sys.exit so that we can get some 19 | # information about where exit is being called. 20 | newexit._old = sys.exit 21 | sys.exit = newexit 22 | 23 | def teardown(): 24 | try: 25 | sys.exit = sys.exit._old 26 | except AttributeError: 27 | sys.exit = sys._exit 28 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/_test_decorators.py: -------------------------------------------------------------------------------- 1 | """Test module for the @-decorator syntax, which is version-specific""" 2 | 3 | from cherrypy import expose, tools 4 | from cherrypy._cpcompat import ntob 5 | 6 | 7 | class ExposeExamples(object): 8 | 9 | @expose 10 | def no_call(self): 11 | return "Mr E. R. Bradshaw" 12 | 13 | @expose() 14 | def call_empty(self): 15 | return "Mrs. B.J. Smegma" 16 | 17 | @expose("call_alias") 18 | def nesbitt(self): 19 | return "Mr Nesbitt" 20 | 21 | @expose(["alias1", "alias2"]) 22 | def andrews(self): 23 | return "Mr Ken Andrews" 24 | 25 | @expose(alias="alias3") 26 | def watson(self): 27 | return "Mr. and Mrs. Watson" 28 | 29 | 30 | class ToolExamples(object): 31 | 32 | @expose 33 | @tools.response_headers(headers=[('Content-Type', 'application/data')]) 34 | def blah(self): 35 | yield ntob("blah") 36 | # This is here to demonstrate that _cp_config = {...} overwrites 37 | # the _cp_config attribute added by the Tool decorator. You have 38 | # to write _cp_config[k] = v or _cp_config.update(...) instead. 39 | blah._cp_config['response.stream'] = True 40 | 41 | 42 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/_test_states_demo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | starttime = time.time() 5 | 6 | import cherrypy 7 | 8 | 9 | class Root: 10 | 11 | def index(self): 12 | return "Hello World" 13 | index.exposed = True 14 | 15 | def mtimes(self): 16 | return repr(cherrypy.engine.publish("Autoreloader", "mtimes")) 17 | mtimes.exposed = True 18 | 19 | def pid(self): 20 | return str(os.getpid()) 21 | pid.exposed = True 22 | 23 | def start(self): 24 | return repr(starttime) 25 | start.exposed = True 26 | 27 | def exit(self): 28 | # This handler might be called before the engine is STARTED if an 29 | # HTTP worker thread handles it before the HTTP server returns 30 | # control to engine.start. We avoid that race condition here 31 | # by waiting for the Bus to be STARTED. 32 | cherrypy.engine.wait(state=cherrypy.engine.states.STARTED) 33 | cherrypy.engine.exit() 34 | exit.exposed = True 35 | 36 | 37 | def unsub_sig(): 38 | cherrypy.log("unsubsig: %s" % cherrypy.config.get('unsubsig', False)) 39 | if cherrypy.config.get('unsubsig', False): 40 | cherrypy.log("Unsubscribing the default cherrypy signal handler") 41 | cherrypy.engine.signal_handler.unsubscribe() 42 | try: 43 | from signal import signal, SIGTERM 44 | except ImportError: 45 | pass 46 | else: 47 | def old_term_handler(signum=None, frame=None): 48 | cherrypy.log("I am an old SIGTERM handler.") 49 | sys.exit(0) 50 | cherrypy.log("Subscribing the new one.") 51 | signal(SIGTERM, old_term_handler) 52 | cherrypy.engine.subscribe('start', unsub_sig, priority=100) 53 | 54 | 55 | def starterror(): 56 | if cherrypy.config.get('starterror', False): 57 | zerodiv = 1 / 0 58 | cherrypy.engine.subscribe('start', starterror, priority=6) 59 | 60 | def log_test_case_name(): 61 | if cherrypy.config.get('test_case_name', False): 62 | cherrypy.log("STARTED FROM: %s" % cherrypy.config.get('test_case_name')) 63 | cherrypy.engine.subscribe('start', log_test_case_name, priority=6) 64 | 65 | 66 | cherrypy.tree.mount(Root(), '/', {'/': {}}) 67 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/checkerdemo.py: -------------------------------------------------------------------------------- 1 | """Demonstration app for cherrypy.checker. 2 | 3 | This application is intentionally broken and badly designed. 4 | To demonstrate the output of the CherryPy Checker, simply execute 5 | this module. 6 | """ 7 | 8 | import os 9 | import cherrypy 10 | thisdir = os.path.dirname(os.path.abspath(__file__)) 11 | 12 | class Root: 13 | pass 14 | 15 | if __name__ == '__main__': 16 | conf = {'/base': {'tools.staticdir.root': thisdir, 17 | # Obsolete key. 18 | 'throw_errors': True, 19 | }, 20 | # This entry should be OK. 21 | '/base/static': {'tools.staticdir.on': True, 22 | 'tools.staticdir.dir': 'static'}, 23 | # Warn on missing folder. 24 | '/base/js': {'tools.staticdir.on': True, 25 | 'tools.staticdir.dir': 'js'}, 26 | # Warn on dir with an abs path even though we provide root. 27 | '/base/static2': {'tools.staticdir.on': True, 28 | 'tools.staticdir.dir': '/static'}, 29 | # Warn on dir with a relative path with no root. 30 | '/static3': {'tools.staticdir.on': True, 31 | 'tools.staticdir.dir': 'static'}, 32 | # Warn on unknown namespace 33 | '/unknown': {'toobles.gzip.on': True}, 34 | # Warn special on cherrypy..* 35 | '/cpknown': {'cherrypy.tools.encode.on': True}, 36 | # Warn on mismatched types 37 | '/conftype': {'request.show_tracebacks': 14}, 38 | # Warn on unknown tool. 39 | '/web': {'tools.unknown.on': True}, 40 | # Warn on server.* in app config. 41 | '/app1': {'server.socket_host': '0.0.0.0'}, 42 | # Warn on 'localhost' 43 | 'global': {'server.socket_host': 'localhost'}, 44 | # Warn on '[name]' 45 | '[/extra_brackets]': {}, 46 | } 47 | cherrypy.quickstart(Root(), config=conf) 48 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/static/dirback.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/third_party/cherrypy/test/static/dirback.jpg -------------------------------------------------------------------------------- /third_party/cherrypy/test/static/has space.html: -------------------------------------------------------------------------------- 1 | Hello, world 2 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/static/index.html: -------------------------------------------------------------------------------- 1 | Hello, world 2 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/style.css: -------------------------------------------------------------------------------- 1 | Dummy stylesheet 2 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/test.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQDBKo554mzIMY+AByUNpaUOP9bJnQ7ZLQe9XgHwoLJR4VzpyZZZ 3 | R9L4WtImEew05FY3Izerfm3MN3+MC0tJ6yQU9sOiU3vBW6RrLIMlfKsnRwBRZ0Kn 4 | da+O6xldVSosu8Ev3z9VZ94iC/ZgKzrH7Mjj/U8/MQO7RBS/LAqee8bFNQIDAQAB 5 | AoGAWOCF0ZrWxn3XMucWq2LNwPKqlvVGwbIwX3cDmX22zmnM4Fy6arXbYh4XlyCj 6 | 9+ofqRrxIFz5k/7tFriTmZ0xag5+Jdx+Kwg0/twiP7XCNKipFogwe1Hznw8OFAoT 7 | enKBdj2+/n2o0Bvo/tDB59m9L/538d46JGQUmJlzMyqYikECQQDyoq+8CtMNvE18 8 | 8VgHcR/KtApxWAjj4HpaHYL637ATjThetUZkW92mgDgowyplthusxdNqhHWyv7E8 9 | tWNdYErZAkEAy85ShTR0M5aWmrE7o0r0SpWInAkNBH9aXQRRARFYsdBtNfRu6I0i 10 | 0lvU9wiu3eF57FMEC86yViZ5UBnQfTu7vQJAVesj/Zt7pwaCDfdMa740OsxMUlyR 11 | MVhhGx4OLpYdPJ8qUecxGQKq13XZ7R1HGyNEY4bd2X80Smq08UFuATfC6QJAH8UB 12 | yBHtKz2GLIcELOg6PIYizW/7v3+6rlVF60yw7sb2vzpjL40QqIn4IKoR2DSVtOkb 13 | 8FtAIX3N21aq0VrGYQJBAIPiaEc2AZ8Bq2GC4F3wOz/BxJ/izvnkiotR12QK4fh5 14 | yjZMhTjWCas5zwHR5PDjlD88AWGDMsZ1PicD4348xJQ= 15 | -----END RSA PRIVATE KEY----- 16 | -----BEGIN CERTIFICATE----- 17 | MIIDxTCCAy6gAwIBAgIJAI18BD7eQxlGMA0GCSqGSIb3DQEBBAUAMIGeMQswCQYD 18 | VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIERpZWdv 19 | MRkwFwYDVQQKExBDaGVycnlQeSBQcm9qZWN0MREwDwYDVQQLEwhkZXYtdGVzdDEW 20 | MBQGA1UEAxMNQ2hlcnJ5UHkgVGVhbTEgMB4GCSqGSIb3DQEJARYRcmVtaUBjaGVy 21 | cnlweS5vcmcwHhcNMDYwOTA5MTkyMDIwWhcNMzQwMTI0MTkyMDIwWjCBnjELMAkG 22 | A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVNhbiBEaWVn 23 | bzEZMBcGA1UEChMQQ2hlcnJ5UHkgUHJvamVjdDERMA8GA1UECxMIZGV2LXRlc3Qx 24 | FjAUBgNVBAMTDUNoZXJyeVB5IFRlYW0xIDAeBgkqhkiG9w0BCQEWEXJlbWlAY2hl 25 | cnJ5cHkub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBKo554mzIMY+A 26 | ByUNpaUOP9bJnQ7ZLQe9XgHwoLJR4VzpyZZZR9L4WtImEew05FY3Izerfm3MN3+M 27 | C0tJ6yQU9sOiU3vBW6RrLIMlfKsnRwBRZ0Knda+O6xldVSosu8Ev3z9VZ94iC/Zg 28 | KzrH7Mjj/U8/MQO7RBS/LAqee8bFNQIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFDIQ 29 | 2feb71tVZCWpU0qJ/Tw+wdtoMIHTBgNVHSMEgcswgciAFDIQ2feb71tVZCWpU0qJ 30 | /Tw+wdtooYGkpIGhMIGeMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p 31 | YTESMBAGA1UEBxMJU2FuIERpZWdvMRkwFwYDVQQKExBDaGVycnlQeSBQcm9qZWN0 32 | MREwDwYDVQQLEwhkZXYtdGVzdDEWMBQGA1UEAxMNQ2hlcnJ5UHkgVGVhbTEgMB4G 33 | CSqGSIb3DQEJARYRcmVtaUBjaGVycnlweS5vcmeCCQCNfAQ+3kMZRjAMBgNVHRME 34 | BTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAL7AAQz7IePV48ZTAFHKr88ntPALsL5S 35 | 8vHCZPNMevNkLTj3DYUw2BcnENxMjm1kou2F2BkvheBPNZKIhc6z4hAml3ed1xa2 36 | D7w6e6OTcstdK/+KrPDDHeOP1dhMWNs2JE1bNlfF1LiXzYKSXpe88eCKjCXsCT/T 37 | NluCaWQys3MS 38 | -----END CERTIFICATE----- 39 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/test_httplib.py: -------------------------------------------------------------------------------- 1 | """Tests for cherrypy/lib/httputil.py.""" 2 | 3 | import unittest 4 | from cherrypy.lib import httputil 5 | 6 | 7 | class UtilityTests(unittest.TestCase): 8 | 9 | def test_urljoin(self): 10 | # Test all slash+atom combinations for SCRIPT_NAME and PATH_INFO 11 | self.assertEqual(httputil.urljoin("/sn/", "/pi/"), "/sn/pi/") 12 | self.assertEqual(httputil.urljoin("/sn/", "/pi"), "/sn/pi") 13 | self.assertEqual(httputil.urljoin("/sn/", "/"), "/sn/") 14 | self.assertEqual(httputil.urljoin("/sn/", ""), "/sn/") 15 | self.assertEqual(httputil.urljoin("/sn", "/pi/"), "/sn/pi/") 16 | self.assertEqual(httputil.urljoin("/sn", "/pi"), "/sn/pi") 17 | self.assertEqual(httputil.urljoin("/sn", "/"), "/sn/") 18 | self.assertEqual(httputil.urljoin("/sn", ""), "/sn") 19 | self.assertEqual(httputil.urljoin("/", "/pi/"), "/pi/") 20 | self.assertEqual(httputil.urljoin("/", "/pi"), "/pi") 21 | self.assertEqual(httputil.urljoin("/", "/"), "/") 22 | self.assertEqual(httputil.urljoin("/", ""), "/") 23 | self.assertEqual(httputil.urljoin("", "/pi/"), "/pi/") 24 | self.assertEqual(httputil.urljoin("", "/pi"), "/pi") 25 | self.assertEqual(httputil.urljoin("", "/"), "/") 26 | self.assertEqual(httputil.urljoin("", ""), "/") 27 | 28 | if __name__ == '__main__': 29 | unittest.main() 30 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/test_refleaks.py: -------------------------------------------------------------------------------- 1 | """Tests for refleaks.""" 2 | 3 | from cherrypy._cpcompat import HTTPConnection, HTTPSConnection, ntob 4 | import threading 5 | 6 | import cherrypy 7 | 8 | 9 | data = object() 10 | 11 | 12 | from cherrypy.test import helper 13 | 14 | 15 | class ReferenceTests(helper.CPWebCase): 16 | 17 | def setup_server(): 18 | 19 | class Root: 20 | def index(self, *args, **kwargs): 21 | cherrypy.request.thing = data 22 | return "Hello world!" 23 | index.exposed = True 24 | 25 | cherrypy.tree.mount(Root()) 26 | setup_server = staticmethod(setup_server) 27 | 28 | def test_threadlocal_garbage(self): 29 | success = [] 30 | 31 | def getpage(): 32 | host = '%s:%s' % (self.interface(), self.PORT) 33 | if self.scheme == 'https': 34 | c = HTTPSConnection(host) 35 | else: 36 | c = HTTPConnection(host) 37 | try: 38 | c.putrequest('GET', '/') 39 | c.endheaders() 40 | response = c.getresponse() 41 | body = response.read() 42 | self.assertEqual(response.status, 200) 43 | self.assertEqual(body, ntob("Hello world!")) 44 | finally: 45 | c.close() 46 | success.append(True) 47 | 48 | ITERATIONS = 25 49 | ts = [] 50 | for _ in range(ITERATIONS): 51 | t = threading.Thread(target=getpage) 52 | ts.append(t) 53 | t.start() 54 | 55 | for t in ts: 56 | t.join() 57 | 58 | self.assertEqual(len(success), ITERATIONS) 59 | 60 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/test_sessionauthenticate.py: -------------------------------------------------------------------------------- 1 | import cherrypy 2 | from cherrypy.test import helper 3 | 4 | 5 | class SessionAuthenticateTest(helper.CPWebCase): 6 | 7 | def setup_server(): 8 | 9 | def check(username, password): 10 | # Dummy check_username_and_password function 11 | if username != 'test' or password != 'password': 12 | return 'Wrong login/password' 13 | 14 | def augment_params(): 15 | # A simple tool to add some things to request.params 16 | # This is to check to make sure that session_auth can handle request 17 | # params (ticket #780) 18 | cherrypy.request.params["test"] = "test" 19 | 20 | cherrypy.tools.augment_params = cherrypy.Tool('before_handler', 21 | augment_params, None, priority=30) 22 | 23 | class Test: 24 | 25 | _cp_config = {'tools.sessions.on': True, 26 | 'tools.session_auth.on': True, 27 | 'tools.session_auth.check_username_and_password': check, 28 | 'tools.augment_params.on': True, 29 | } 30 | 31 | def index(self, **kwargs): 32 | return "Hi %s, you are logged in" % cherrypy.request.login 33 | index.exposed = True 34 | 35 | cherrypy.tree.mount(Test()) 36 | setup_server = staticmethod(setup_server) 37 | 38 | 39 | def testSessionAuthenticate(self): 40 | # request a page and check for login form 41 | self.getPage('/') 42 | self.assertInBody('
') 43 | 44 | # setup credentials 45 | login_body = 'username=test&password=password&from_page=/' 46 | 47 | # attempt a login 48 | self.getPage('/do_login', method='POST', body=login_body) 49 | self.assertStatus((302, 303)) 50 | 51 | # get the page now that we are logged in 52 | self.getPage('/', self.cookies) 53 | self.assertBody('Hi test, you are logged in') 54 | 55 | # do a logout 56 | self.getPage('/do_logout', self.cookies, method='POST') 57 | self.assertStatus((302, 303)) 58 | 59 | # verify we are logged out 60 | self.getPage('/', self.cookies) 61 | self.assertInBody('') 62 | 63 | -------------------------------------------------------------------------------- /third_party/cherrypy/test/test_wsgi_vhost.py: -------------------------------------------------------------------------------- 1 | import cherrypy 2 | from cherrypy.test import helper 3 | 4 | 5 | class WSGI_VirtualHost_Test(helper.CPWebCase): 6 | 7 | def setup_server(): 8 | 9 | class ClassOfRoot(object): 10 | 11 | def __init__(self, name): 12 | self.name = name 13 | 14 | def index(self): 15 | return "Welcome to the %s website!" % self.name 16 | index.exposed = True 17 | 18 | 19 | default = cherrypy.Application(None) 20 | 21 | domains = {} 22 | for year in range(1997, 2008): 23 | app = cherrypy.Application(ClassOfRoot('Class of %s' % year)) 24 | domains['www.classof%s.example' % year] = app 25 | 26 | cherrypy.tree.graft(cherrypy._cpwsgi.VirtualHost(default, domains)) 27 | setup_server = staticmethod(setup_server) 28 | 29 | def test_welcome(self): 30 | if not cherrypy.server.using_wsgi: 31 | return self.skip("skipped (not using WSGI)... ") 32 | 33 | for year in range(1997, 2008): 34 | self.getPage("/", headers=[('Host', 'www.classof%s.example' % year)]) 35 | self.assertBody("Welcome to the Class of %s website!" % year) 36 | 37 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/README.txt: -------------------------------------------------------------------------------- 1 | CherryPy Tutorials 2 | ------------------------------------------------------------------------ 3 | 4 | This is a series of tutorials explaining how to develop dynamic web 5 | applications using CherryPy. A couple of notes: 6 | 7 | - Each of these tutorials builds on the ones before it. If you're 8 | new to CherryPy, we recommend you start with 01_helloworld.py and 9 | work your way upwards. :) 10 | 11 | - In most of these tutorials, you will notice that all output is done 12 | by returning normal Python strings, often using simple Python 13 | variable substitution. In most real-world applications, you will 14 | probably want to use a separate template package (like Cheetah, 15 | CherryTemplate or XML/XSL). 16 | 17 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # This is used in test_config to test unrepr of "from A import B" 3 | thing2 = object() -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/custom_error.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 403 Unauthorized 7 | 8 | 9 |

You can't do that!

10 |

%(message)s

11 |

This is a custom error page that is read from a file.

12 |

%(traceback)s
13 | 14 | 15 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/pdf_file.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-archive/pub-dartlang/816223bb2084e9002244850a3ecca29ec0fd4611/third_party/cherrypy/tutorial/pdf_file.pdf -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut01_helloworld.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tutorial - Hello World 3 | 4 | The most basic (working) CherryPy application possible. 5 | """ 6 | 7 | # Import CherryPy global namespace 8 | import cherrypy 9 | 10 | class HelloWorld: 11 | """ Sample request handler class. """ 12 | 13 | def index(self): 14 | # CherryPy will call this method for the root URI ("/") and send 15 | # its return value to the client. Because this is tutorial 16 | # lesson number 01, we'll just send something really simple. 17 | # How about... 18 | return "Hello world!" 19 | 20 | # Expose the index method through the web. CherryPy will never 21 | # publish methods that don't have the exposed attribute set to True. 22 | index.exposed = True 23 | 24 | 25 | import os.path 26 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 27 | 28 | if __name__ == '__main__': 29 | # CherryPy always starts with app.root when trying to map request URIs 30 | # to objects, so we need to mount a request handler root. A request 31 | # to '/' will be mapped to HelloWorld().index(). 32 | cherrypy.quickstart(HelloWorld(), config=tutconf) 33 | else: 34 | # This branch is for the test suite; you can ignore it. 35 | cherrypy.tree.mount(HelloWorld(), config=tutconf) 36 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut02_expose_methods.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tutorial - Multiple methods 3 | 4 | This tutorial shows you how to link to other methods of your request 5 | handler. 6 | """ 7 | 8 | import cherrypy 9 | 10 | class HelloWorld: 11 | 12 | def index(self): 13 | # Let's link to another method here. 14 | return 'We have an important message for you!' 15 | index.exposed = True 16 | 17 | def showMessage(self): 18 | # Here's the important message! 19 | return "Hello world!" 20 | showMessage.exposed = True 21 | 22 | import os.path 23 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 24 | 25 | if __name__ == '__main__': 26 | # CherryPy always starts with app.root when trying to map request URIs 27 | # to objects, so we need to mount a request handler root. A request 28 | # to '/' will be mapped to HelloWorld().index(). 29 | cherrypy.quickstart(HelloWorld(), config=tutconf) 30 | else: 31 | # This branch is for the test suite; you can ignore it. 32 | cherrypy.tree.mount(HelloWorld(), config=tutconf) 33 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut03_get_and_post.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tutorial - Passing variables 3 | 4 | This tutorial shows you how to pass GET/POST variables to methods. 5 | """ 6 | 7 | import cherrypy 8 | 9 | 10 | class WelcomePage: 11 | 12 | def index(self): 13 | # Ask for the user's name. 14 | return ''' 15 | 16 | What is your name? 17 | 18 | 19 |
''' 20 | index.exposed = True 21 | 22 | def greetUser(self, name = None): 23 | # CherryPy passes all GET and POST variables as method parameters. 24 | # It doesn't make a difference where the variables come from, how 25 | # large their contents are, and so on. 26 | # 27 | # You can define default parameter values as usual. In this 28 | # example, the "name" parameter defaults to None so we can check 29 | # if a name was actually specified. 30 | 31 | if name: 32 | # Greet the user! 33 | return "Hey %s, what's up?" % name 34 | else: 35 | if name is None: 36 | # No name was specified 37 | return 'Please enter your name here.' 38 | else: 39 | return 'No, really, enter your name here.' 40 | greetUser.exposed = True 41 | 42 | 43 | import os.path 44 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 45 | 46 | if __name__ == '__main__': 47 | # CherryPy always starts with app.root when trying to map request URIs 48 | # to objects, so we need to mount a request handler root. A request 49 | # to '/' will be mapped to HelloWorld().index(). 50 | cherrypy.quickstart(WelcomePage(), config=tutconf) 51 | else: 52 | # This branch is for the test suite; you can ignore it. 53 | cherrypy.tree.mount(WelcomePage(), config=tutconf) 54 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut05_derived_objects.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tutorial - Object inheritance 3 | 4 | You are free to derive your request handler classes from any base 5 | class you wish. In most real-world applications, you will probably 6 | want to create a central base class used for all your pages, which takes 7 | care of things like printing a common page header and footer. 8 | """ 9 | 10 | import cherrypy 11 | 12 | 13 | class Page: 14 | # Store the page title in a class attribute 15 | title = 'Untitled Page' 16 | 17 | def header(self): 18 | return ''' 19 | 20 | 21 | %s 22 | 23 | 24 |

%s

25 | ''' % (self.title, self.title) 26 | 27 | def footer(self): 28 | return ''' 29 | 30 | 31 | ''' 32 | 33 | # Note that header and footer don't get their exposed attributes 34 | # set to True. This isn't necessary since the user isn't supposed 35 | # to call header or footer directly; instead, we'll call them from 36 | # within the actually exposed handler methods defined in this 37 | # class' subclasses. 38 | 39 | 40 | class HomePage(Page): 41 | # Different title for this page 42 | title = 'Tutorial 5' 43 | 44 | def __init__(self): 45 | # create a subpage 46 | self.another = AnotherPage() 47 | 48 | def index(self): 49 | # Note that we call the header and footer methods inherited 50 | # from the Page class! 51 | return self.header() + ''' 52 |

53 | Isn't this exciting? There's 54 | another page, too! 55 |

56 | ''' + self.footer() 57 | index.exposed = True 58 | 59 | 60 | class AnotherPage(Page): 61 | title = 'Another Page' 62 | 63 | def index(self): 64 | return self.header() + ''' 65 |

66 | And this is the amazing second page! 67 |

68 | ''' + self.footer() 69 | index.exposed = True 70 | 71 | 72 | import os.path 73 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 74 | 75 | if __name__ == '__main__': 76 | # CherryPy always starts with app.root when trying to map request URIs 77 | # to objects, so we need to mount a request handler root. A request 78 | # to '/' will be mapped to HelloWorld().index(). 79 | cherrypy.quickstart(HomePage(), config=tutconf) 80 | else: 81 | # This branch is for the test suite; you can ignore it. 82 | cherrypy.tree.mount(HomePage(), config=tutconf) 83 | 84 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut06_default_method.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tutorial - The default method 3 | 4 | Request handler objects can implement a method called "default" that 5 | is called when no other suitable method/object could be found. 6 | Essentially, if CherryPy2 can't find a matching request handler object 7 | for the given request URI, it will use the default method of the object 8 | located deepest on the URI path. 9 | 10 | Using this mechanism you can easily simulate virtual URI structures 11 | by parsing the extra URI string, which you can access through 12 | cherrypy.request.virtualPath. 13 | 14 | The application in this tutorial simulates an URI structure looking 15 | like /users/. Since the bit will not be found (as 16 | there are no matching methods), it is handled by the default method. 17 | """ 18 | 19 | import cherrypy 20 | 21 | 22 | class UsersPage: 23 | 24 | def index(self): 25 | # Since this is just a stupid little example, we'll simply 26 | # display a list of links to random, made-up users. In a real 27 | # application, this could be generated from a database result set. 28 | return ''' 29 | Remi Delon
30 | Hendrik Mans
31 | Lorenzo Lamas
32 | ''' 33 | index.exposed = True 34 | 35 | def default(self, user): 36 | # Here we react depending on the virtualPath -- the part of the 37 | # path that could not be mapped to an object method. In a real 38 | # application, we would probably do some database lookups here 39 | # instead of the silly if/elif/else construct. 40 | if user == 'remi': 41 | out = "Remi Delon, CherryPy lead developer" 42 | elif user == 'hendrik': 43 | out = "Hendrik Mans, CherryPy co-developer & crazy German" 44 | elif user == 'lorenzo': 45 | out = "Lorenzo Lamas, famous actor and singer!" 46 | else: 47 | out = "Unknown user. :-(" 48 | 49 | return '%s (back)' % out 50 | default.exposed = True 51 | 52 | 53 | import os.path 54 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 55 | 56 | if __name__ == '__main__': 57 | # CherryPy always starts with app.root when trying to map request URIs 58 | # to objects, so we need to mount a request handler root. A request 59 | # to '/' will be mapped to HelloWorld().index(). 60 | cherrypy.quickstart(UsersPage(), config=tutconf) 61 | else: 62 | # This branch is for the test suite; you can ignore it. 63 | cherrypy.tree.mount(UsersPage(), config=tutconf) 64 | 65 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut07_sessions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tutorial - Sessions 3 | 4 | Storing session data in CherryPy applications is very easy: cherrypy 5 | provides a dictionary called "session" that represents the session 6 | data for the current user. If you use RAM based sessions, you can store 7 | any kind of object into that dictionary; otherwise, you are limited to 8 | objects that can be pickled. 9 | """ 10 | 11 | import cherrypy 12 | 13 | 14 | class HitCounter: 15 | 16 | _cp_config = {'tools.sessions.on': True} 17 | 18 | def index(self): 19 | # Increase the silly hit counter 20 | count = cherrypy.session.get('count', 0) + 1 21 | 22 | # Store the new value in the session dictionary 23 | cherrypy.session['count'] = count 24 | 25 | # And display a silly hit count message! 26 | return ''' 27 | During your current session, you've viewed this 28 | page %s times! Your life is a patio of fun! 29 | ''' % count 30 | index.exposed = True 31 | 32 | 33 | import os.path 34 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 35 | 36 | if __name__ == '__main__': 37 | # CherryPy always starts with app.root when trying to map request URIs 38 | # to objects, so we need to mount a request handler root. A request 39 | # to '/' will be mapped to HelloWorld().index(). 40 | cherrypy.quickstart(HitCounter(), config=tutconf) 41 | else: 42 | # This branch is for the test suite; you can ignore it. 43 | cherrypy.tree.mount(HitCounter(), config=tutconf) 44 | 45 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tut08_generators_and_yield.py: -------------------------------------------------------------------------------- 1 | """ 2 | Bonus Tutorial: Using generators to return result bodies 3 | 4 | Instead of returning a complete result string, you can use the yield 5 | statement to return one result part after another. This may be convenient 6 | in situations where using a template package like CherryPy or Cheetah 7 | would be overkill, and messy string concatenation too uncool. ;-) 8 | """ 9 | 10 | import cherrypy 11 | 12 | 13 | class GeneratorDemo: 14 | 15 | def header(self): 16 | return "

Generators rule!

" 17 | 18 | def footer(self): 19 | return "" 20 | 21 | def index(self): 22 | # Let's make up a list of users for presentation purposes 23 | users = ['Remi', 'Carlos', 'Hendrik', 'Lorenzo Lamas'] 24 | 25 | # Every yield line adds one part to the total result body. 26 | yield self.header() 27 | yield "

List of users:

" 28 | 29 | for user in users: 30 | yield "%s
" % user 31 | 32 | yield self.footer() 33 | index.exposed = True 34 | 35 | 36 | import os.path 37 | tutconf = os.path.join(os.path.dirname(__file__), 'tutorial.conf') 38 | 39 | if __name__ == '__main__': 40 | # CherryPy always starts with app.root when trying to map request URIs 41 | # to objects, so we need to mount a request handler root. A request 42 | # to '/' will be mapped to HelloWorld().index(). 43 | cherrypy.quickstart(GeneratorDemo(), config=tutconf) 44 | else: 45 | # This branch is for the test suite; you can ignore it. 46 | cherrypy.tree.mount(GeneratorDemo(), config=tutconf) 47 | 48 | -------------------------------------------------------------------------------- /third_party/cherrypy/tutorial/tutorial.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | server.socket_host = "127.0.0.1" 3 | server.socket_port = 8080 4 | server.thread_pool = 10 5 | -------------------------------------------------------------------------------- /third_party/cherrypy/wsgiserver/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['HTTPRequest', 'HTTPConnection', 'HTTPServer', 2 | 'SizeCheckWrapper', 'KnownLengthRFile', 'ChunkedRFile', 3 | 'MaxSizeExceeded', 'NoSSLError', 'FatalSSLAlert', 4 | 'WorkerThread', 'ThreadPool', 'SSLAdapter', 5 | 'CherryPyWSGIServer', 6 | 'Gateway', 'WSGIGateway', 'WSGIGateway_10', 'WSGIGateway_u0', 7 | 'WSGIPathInfoDispatcher', 'get_ssl_adapter_class'] 8 | 9 | import sys 10 | if sys.version_info < (3, 0): 11 | from wsgiserver2 import * 12 | else: 13 | # Le sigh. Boo for backward-incompatible syntax. 14 | exec('from .wsgiserver3 import *') 15 | -------------------------------------------------------------------------------- /third_party/cloud_storage/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include distribute_setup.py 2 | -------------------------------------------------------------------------------- /third_party/cloud_storage/README: -------------------------------------------------------------------------------- 1 | AppEngine Google Cloud Storage clients 2 | ====================================== 3 | 4 | Check the site for up to date status, latest version, getting started & user 5 | guides. 6 | -------------------------------------------------------------------------------- /third_party/cloud_storage/cloudstorage/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, 10 | # software distributed under the License is distributed on an 11 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 12 | # either express or implied. See the License for the specific 13 | # language governing permissions and limitations under the License. 14 | 15 | """Client Library for Google Cloud Storage.""" 16 | 17 | 18 | 19 | 20 | from .api_utils import RetryParams 21 | from .api_utils import set_default_retry_params 22 | from cloudstorage_api import * 23 | from .common import CSFileStat 24 | from .common import GCSFileStat 25 | from .common import validate_bucket_name 26 | from .common import validate_bucket_path 27 | from .common import validate_file_path 28 | from errors import * 29 | from storage_api import * 30 | -------------------------------------------------------------------------------- /third_party/cloud_storage/cloudstorage/test_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, 10 | # software distributed under the License is distributed on an 11 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 12 | # either express or implied. See the License for the specific 13 | # language governing permissions and limitations under the License. 14 | 15 | """Utils for testing.""" 16 | 17 | 18 | class MockUrlFetchResult(object): 19 | 20 | def __init__(self, status, headers, body): 21 | self.status_code = status 22 | self.headers = headers 23 | self.content = body 24 | self.content_was_truncated = False 25 | self.final_url = None 26 | -------------------------------------------------------------------------------- /third_party/cloud_storage/setup.py: -------------------------------------------------------------------------------- 1 | """Setup specs for packaging, distributing, and installing gcs lib.""" 2 | 3 | import distribute_setup 4 | distribute_setup.use_setuptools() 5 | 6 | 7 | import setuptools 8 | 9 | 10 | setuptools.setup( 11 | name="GoogleAppEngineCloudStorageClient", 12 | version="1.9.15.0", 13 | packages=setuptools.find_packages(), 14 | author="Google App Engine", 15 | author_email="app-engine-pipeline-api@googlegroups.com", 16 | keywords="google app engine cloud storage", 17 | url="https://code.google.com/p/appengine-gcs-client/", 18 | license="Apache License 2.0", 19 | description=("This library is the preferred way of accessing Google " 20 | "Cloud Storage from App Engine. It was designed to " 21 | "replace the Files API. As a result it contains much " 22 | "of the same functionality (streaming reads and writes but " 23 | "not the complete set of GCS APIs). It also provides key " 24 | "stability improvements and a better overall developer " 25 | "experience."), 26 | exclude_package_data={"": ["README"]}, 27 | zip_safe=True, 28 | ) 29 | -------------------------------------------------------------------------------- /third_party/feedgen/ext/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | =========== 4 | feedgen.ext 5 | =========== 6 | """ 7 | -------------------------------------------------------------------------------- /third_party/feedgen/ext/base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | feedgen.ext.base 4 | ~~~~~~~~~~~~~~~~ 5 | 6 | Basic FeedGenerator extension which does nothing but provides all necessary 7 | methods. 8 | 9 | :copyright: 2013, Lars Kiesow 10 | 11 | :license: FreeBSD and LGPL, see license.* for more details. 12 | ''' 13 | 14 | 15 | class BaseExtension(object): 16 | '''Basic FeedGenerator extension. 17 | ''' 18 | def extend_ns(self): 19 | '''Returns a dict that will be used in the namespace map for the feed.''' 20 | return dict() 21 | 22 | def extend_rss(self, feed): 23 | '''Extend a RSS feed xml structure containing all previously set fields. 24 | 25 | :param feed: The feed xml root element. 26 | :returns: The feed root element. 27 | ''' 28 | return feed 29 | 30 | 31 | def extend_atom(self, feed): 32 | '''Extend an ATOM feed xml structure containing all previously set 33 | fields. 34 | 35 | :param feed: The feed xml root element. 36 | :returns: The feed root element. 37 | ''' 38 | return feed 39 | 40 | 41 | class BaseEntryExtension(BaseExtension): 42 | '''Basic FeedEntry extension. 43 | ''' 44 | -------------------------------------------------------------------------------- /third_party/feedgen/util.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | feedgen.util 4 | ~~~~~~~~~~~~ 5 | 6 | This file contains helper functions for the feed generator module. 7 | 8 | :copyright: 2013, Lars Kiesow 9 | :license: FreeBSD and LGPL, see license.* for more details. 10 | ''' 11 | import sys 12 | 13 | 14 | def ensure_format(val, allowed, required, allowed_values=None, defaults=None): 15 | '''Takes a dictionary or a list of dictionaries and check if all keys are in 16 | the set of allowed keys, if all required keys are present and if the values 17 | of a specific key are ok. 18 | 19 | :param val: Dictionaries to check. 20 | :param allowed: Set of allowed keys. 21 | :param required: Set of required keys. 22 | :param allowed_values: Dictionary with keys and sets of their allowed values. 23 | :param defaults: Dictionary with default values. 24 | :returns: List of checked dictionaries. 25 | ''' 26 | if not val: 27 | return None 28 | if allowed_values is None: 29 | allowed_values = {} 30 | if defaults is None: 31 | defaults = {} 32 | # Make shure that we have a list of dicts. Even if there is only one. 33 | if not isinstance(val, list): 34 | val = [val] 35 | for elem in val: 36 | if not isinstance(elem, dict): 37 | raise ValueError('Invalid data (value is no dictionary)') 38 | # Set default values 39 | 40 | version = sys.version_info[0] 41 | 42 | if version == 2: 43 | items = defaults.iteritems() 44 | else: 45 | items = defaults.items() 46 | 47 | for k,v in items: 48 | elem[k] = elem.get(k, v) 49 | if not set(elem.keys()) <= allowed: 50 | raise ValueError('Data contains invalid keys') 51 | if not set(elem.keys()) >= required: 52 | raise ValueError('Data contains not all required keys') 53 | 54 | if version == 2: 55 | values = allowed_values.iteritems() 56 | else: 57 | values = allowed_values.items() 58 | 59 | for k,v in values: 60 | if elem.get(k) and not elem[k] in v: 61 | raise ValueError('Invalid value for %s' % k ) 62 | return val 63 | -------------------------------------------------------------------------------- /third_party/feedgen/version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | feedgen.version 4 | ~~~~~~~~~~~~~~~ 5 | 6 | :copyright: 2013-2014, Lars Kiesow 7 | 8 | :license: FreeBSD and LGPL, see license.* for more details. 9 | 10 | ''' 11 | 12 | 'Version of python-feedgen represented as tuple' 13 | version = (0, 3, 0) 14 | 15 | 16 | 'Version of python-feedgen represented as string' 17 | version_str = '.'.join([str(x) for x in version]) 18 | 19 | version_major = version[:1] 20 | version_minor = version[:2] 21 | version_full = version 22 | 23 | version_major_str = '.'.join([str(x) for x in version_major]) 24 | version_minor_str = '.'.join([str(x) for x in version_minor]) 25 | version_full_str = '.'.join([str(x) for x in version_full]) 26 | -------------------------------------------------------------------------------- /third_party/gfm/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012, the Dart project authors. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above 8 | copyright notice, this list of conditions and the following 9 | disclaimer in the documentation and/or other materials provided 10 | with the distribution. 11 | * Neither the name of Google Inc. nor the names of its 12 | contributors may be used to endorse or promote products derived 13 | from this software without specific prior written permission. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /third_party/gfm/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import autolink 6 | import automail 7 | import hidden_hilite 8 | import semi_sane_lists 9 | 10 | AutolinkExtension = autolink.AutolinkExtension 11 | AutomailExtension = automail.AutomailExtension 12 | HiddenHiliteExtension = hidden_hilite.HiddenHiliteExtension 13 | SemiSaneListExtension = semi_sane_lists.SemiSaneListExtension 14 | -------------------------------------------------------------------------------- /third_party/gfm/autolink.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 | # for details. All rights reserved. Use of this source code is governed by a 4 | # BSD-style license that can be found in the LICENSE file. 5 | 6 | import re 7 | import markdown 8 | 9 | # We can't re-use the built-in AutolinkPattern because we need to add protocols 10 | # to links without them. 11 | class AutolinkPattern(markdown.inlinepatterns.Pattern): 12 | def handleMatch(self, m): 13 | el = markdown.util.etree.Element("a") 14 | 15 | href = m.group(2) 16 | if not re.match('^(ftp|https?)://', href, flags=re.IGNORECASE): 17 | href = 'http://%s' % href 18 | el.set('href', self.unescape(href)) 19 | 20 | el.text = markdown.util.AtomicString(m.group(2)) 21 | return el 22 | 23 | class AutolinkExtension(markdown.Extension): 24 | """An extension that turns all URLs into links. 25 | 26 | This is based on the web-only URL regex by John Gruber that's listed on 27 | http://daringfireball.net/2010/07/improved_regex_for_matching_urls (which is 28 | in the public domain). 29 | 30 | This regex seems to line up pretty closely with GitHub's URL matching. There 31 | are only two cases I've found where they differ. In both cases, I've 32 | modified the regex slightly to bring it in line with GitHub's parsing: 33 | 34 | * GitHub accepts FTP-protocol URLs. 35 | * GitHub only accepts URLs with protocols or "www.", whereas Gruber's regex 36 | accepts things like "foo.com/bar". 37 | """ 38 | 39 | def extendMarkdown(self, md, md_globals): 40 | url_re = r'(?i)\b((?:(?:ftp|https?)://|www\d{0,3}[.])(?:[^\s()<>]+|' + \ 41 | r'\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()' + \ 42 | r'<>]+\)))*\)|[^\s`!()\[\]{};:' + r"'" + ur'".,<>?«»“”‘’]))' 43 | autolink = AutolinkPattern(url_re, md) 44 | md.inlinePatterns.add('gfm-autolink', autolink, '_end') 45 | -------------------------------------------------------------------------------- /third_party/gfm/automail.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 | # for details. All rights reserved. Use of this source code is governed by a 4 | # BSD-style license that can be found in the LICENSE file. 5 | 6 | import re 7 | import markdown 8 | 9 | # We can't re-use the built-in AutomailPattern because we need to add mailto:. 10 | # We also don't care about HTML-encoding the email. 11 | class AutomailPattern(markdown.inlinepatterns.Pattern): 12 | def handleMatch(self, m): 13 | el = markdown.util.etree.Element("a") 14 | el.set('href', self.unescape('mailto:' + m.group(2))) 15 | el.text = markdown.util.AtomicString(m.group(2)) 16 | return el 17 | 18 | class AutomailExtension(markdown.Extension): 19 | """An extension that turns all email addresses into links.""" 20 | 21 | def extendMarkdown(self, md, md_globals): 22 | mail_re = r'\b(?i)([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]+)\b' 23 | automail = AutomailPattern(mail_re, md) 24 | md.inlinePatterns.add('gfm-automail', automail, '_end') 25 | -------------------------------------------------------------------------------- /third_party/gfm/hidden_hilite.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from markdown.extensions.codehilite import CodeHiliteExtension 6 | 7 | class HiddenHiliteExtension(CodeHiliteExtension): 8 | """A subclass of CodeHiliteExtension that doesn't highlight on its own. 9 | 10 | This just enables the fenced code extension to use syntax highlighting, 11 | without adding syntax highlighting or line numbers to any additional code 12 | blocks. 13 | """ 14 | 15 | def extendMarkdown(self, md, md_globals): 16 | md.registerExtension(self) 17 | -------------------------------------------------------------------------------- /third_party/gfm/semi_sane_lists.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | import re 6 | import markdown 7 | 8 | class SemiSaneOListProcessor(markdown.blockprocessors.OListProcessor): 9 | SIBLING_TAGS = ['ol'] 10 | 11 | class SemiSaneUListProcessor(markdown.blockprocessors.UListProcessor): 12 | SIBLING_TAGS = ['ul'] 13 | 14 | class SemiSaneListExtension(markdown.Extension): 15 | """An extension that causes lists to be treated the same way GitHub does. 16 | 17 | Like the sane_lists extension, GitHub considers a list to end if it's 18 | separated by multiple newlines from another list of a different type. Unlike 19 | the sane_lists extension, GitHub will mix list types if they're not 20 | separated by multiple newlines. 21 | 22 | Github also recognizes lists that start in the middle of a paragraph. This 23 | is currently not supported by this extension, since the Python parser has a 24 | deeply-ingrained belief that blocks are always separated by multiple 25 | newlines. 26 | """ 27 | 28 | def extendMarkdown(self, md, md_globals): 29 | md.parser.blockprocessors['olist'] = SemiSaneOListProcessor(md.parser) 30 | md.parser.blockprocessors['ulist'] = SemiSaneUListProcessor(md.parser) 31 | -------------------------------------------------------------------------------- /third_party/markdown/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later) 2 | Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) 3 | Copyright 2004 Manfred Stienstra (the original version) 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of the nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT 23 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | 31 | -------------------------------------------------------------------------------- /third_party/markdown/etree_loader.py: -------------------------------------------------------------------------------- 1 | 2 | ## Import 3 | def importETree(): 4 | """Import the best implementation of ElementTree, return a module object.""" 5 | etree_in_c = None 6 | try: # Is it Python 2.5+ with C implemenation of ElementTree installed? 7 | import xml.etree.cElementTree as etree_in_c 8 | from xml.etree.ElementTree import Comment 9 | except ImportError: 10 | try: # Is it Python 2.5+ with Python implementation of ElementTree? 11 | import xml.etree.ElementTree as etree 12 | except ImportError: 13 | try: # An earlier version of Python with cElementTree installed? 14 | import cElementTree as etree_in_c 15 | from elementtree.ElementTree import Comment 16 | except ImportError: 17 | try: # An earlier version of Python with Python ElementTree? 18 | import elementtree.ElementTree as etree 19 | except ImportError: 20 | raise ImportError("Failed to import ElementTree") 21 | if etree_in_c: 22 | if etree_in_c.VERSION < "1.0.5": 23 | raise RuntimeError("cElementTree version 1.0.5 or higher is required.") 24 | # Third party serializers (including ours) test with non-c Comment 25 | etree_in_c.test_comment = Comment 26 | return etree_in_c 27 | elif etree.VERSION < "1.1": 28 | raise RuntimeError("ElementTree version 1.1 or higher is required") 29 | else: 30 | return etree 31 | 32 | -------------------------------------------------------------------------------- /third_party/markdown/extensions/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Extensions 3 | ----------------------------------------------------------------------------- 4 | """ 5 | 6 | class Extension: 7 | """ Base class for extensions to subclass. """ 8 | def __init__(self, configs = {}): 9 | """Create an instance of an Extention. 10 | 11 | Keyword arguments: 12 | 13 | * configs: A dict of configuration setting used by an Extension. 14 | """ 15 | self.config = configs 16 | 17 | def getConfig(self, key, default=''): 18 | """ Return a setting for the given key or an empty string. """ 19 | if key in self.config: 20 | return self.config[key][0] 21 | else: 22 | return default 23 | 24 | def getConfigs(self): 25 | """ Return all configs settings as a dict. """ 26 | return dict([(key, self.getConfig(key)) for key in self.config.keys()]) 27 | 28 | def getConfigInfo(self): 29 | """ Return all config descriptions as a list of tuples. """ 30 | return [(key, self.config[key][1]) for key in self.config.keys()] 31 | 32 | def setConfig(self, key, value): 33 | """ Set a config setting for `key` with the given `value`. """ 34 | self.config[key][0] = value 35 | 36 | def extendMarkdown(self, md, md_globals): 37 | """ 38 | Add the various proccesors and patterns to the Markdown Instance. 39 | 40 | This method must be overriden by every extension. 41 | 42 | Keyword arguments: 43 | 44 | * md: The Markdown instance. 45 | 46 | * md_globals: Global variables in the markdown module namespace. 47 | 48 | """ 49 | raise NotImplementedError, 'Extension "%s.%s" must define an "extendMarkdown"' \ 50 | 'method.' % (self.__class__.__module__, self.__class__.__name__) 51 | 52 | -------------------------------------------------------------------------------- /third_party/markdown/extensions/extra.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Python-Markdown Extra Extension 4 | =============================== 5 | 6 | A compilation of various Python-Markdown extensions that imitates 7 | [PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/). 8 | 9 | Note that each of the individual extensions still need to be available 10 | on your PYTHONPATH. This extension simply wraps them all up as a 11 | convenience so that only one extension needs to be listed when 12 | initiating Markdown. See the documentation for each individual 13 | extension for specifics about that extension. 14 | 15 | In the event that one or more of the supported extensions are not 16 | available for import, Markdown will issue a warning and simply continue 17 | without that extension. 18 | 19 | There may be additional extensions that are distributed with 20 | Python-Markdown that are not included here in Extra. Those extensions 21 | are not part of PHP Markdown Extra, and therefore, not part of 22 | Python-Markdown Extra. If you really would like Extra to include 23 | additional extensions, we suggest creating your own clone of Extra 24 | under a differant name. You could also edit the `extensions` global 25 | variable defined below, but be aware that such changes may be lost 26 | when you upgrade to any future version of Python-Markdown. 27 | 28 | """ 29 | 30 | import markdown 31 | 32 | extensions = ['smart_strong', 33 | 'fenced_code', 34 | 'footnotes', 35 | 'attr_list', 36 | 'def_list', 37 | 'tables', 38 | 'abbr', 39 | ] 40 | 41 | 42 | class ExtraExtension(markdown.Extension): 43 | """ Add various extensions to Markdown class.""" 44 | 45 | def extendMarkdown(self, md, md_globals): 46 | """ Register extension instances. """ 47 | md.registerExtensions(extensions, self.config) 48 | # Turn on processing of markdown text within raw html 49 | md.preprocessors['html_block'].markdown_in_raw = True 50 | 51 | def makeExtension(configs={}): 52 | return ExtraExtension(configs=dict(configs)) 53 | -------------------------------------------------------------------------------- /third_party/markdown/extensions/html_tidy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | HTML Tidy Extension for Python-Markdown 5 | ======================================= 6 | 7 | Runs [HTML Tidy][] on the output of Python-Markdown using the [uTidylib][] 8 | Python wrapper. Both libtidy and uTidylib must be installed on your system. 9 | 10 | Note than any Tidy [options][] can be passed in as extension configs. So, 11 | for example, to output HTML rather than XHTML, set ``output_xhtml=0``. To 12 | indent the output, set ``indent=auto`` and to have Tidy wrap the output in 13 | ```` and ```` tags, set ``show_body_only=0``. 14 | 15 | [HTML Tidy]: http://tidy.sourceforge.net/ 16 | [uTidylib]: http://utidylib.berlios.de/ 17 | [options]: http://tidy.sourceforge.net/docs/quickref.html 18 | 19 | Copyright (c)2008 [Waylan Limberg](http://achinghead.com) 20 | 21 | License: [BSD](http://www.opensource.org/licenses/bsd-license.php) 22 | 23 | Dependencies: 24 | * [Python2.3+](http://python.org) 25 | * [Markdown 2.0+](http://packages.python.org/Markdown/) 26 | * [HTML Tidy](http://utidylib.berlios.de/) 27 | * [uTidylib](http://utidylib.berlios.de/) 28 | 29 | """ 30 | 31 | import markdown 32 | try: 33 | import tidy 34 | except ImportError: 35 | tidy = None 36 | 37 | class TidyExtension(markdown.Extension): 38 | 39 | def __init__(self, configs): 40 | # Set defaults to match typical markdown behavior. 41 | self.config = dict(output_xhtml=1, 42 | show_body_only=1, 43 | char_encoding='utf8' 44 | ) 45 | # Merge in user defined configs overriding any present if nessecary. 46 | for c in configs: 47 | self.config[c[0]] = c[1] 48 | 49 | def extendMarkdown(self, md, md_globals): 50 | # Save options to markdown instance 51 | md.tidy_options = self.config 52 | # Add TidyProcessor to postprocessors 53 | if tidy: 54 | md.postprocessors['tidy'] = TidyProcessor(md) 55 | 56 | 57 | class TidyProcessor(markdown.postprocessors.Postprocessor): 58 | 59 | def run(self, text): 60 | # Pass text to Tidy. As Tidy does not accept unicode we need to encode 61 | # it and decode its return value. 62 | enc = self.markdown.tidy_options.get('char_encoding', 'utf8') 63 | return unicode(tidy.parseString(text.encode(enc), 64 | **self.markdown.tidy_options), 65 | encoding=enc) 66 | 67 | 68 | def makeExtension(configs=None): 69 | return TidyExtension(configs=configs) 70 | -------------------------------------------------------------------------------- /third_party/markdown/extensions/nl2br.py: -------------------------------------------------------------------------------- 1 | """ 2 | NL2BR Extension 3 | =============== 4 | 5 | A Python-Markdown extension to treat newlines as hard breaks; like 6 | GitHub-flavored Markdown does. 7 | 8 | Usage: 9 | 10 | >>> import markdown 11 | >>> print markdown.markdown('line 1\\nline 2', extensions=['nl2br']) 12 |

line 1
13 | line 2

14 | 15 | Copyright 2011 [Brian Neal](http://deathofagremmie.com/) 16 | 17 | Dependencies: 18 | * [Python 2.4+](http://python.org) 19 | * [Markdown 2.1+](http://packages.python.org/Markdown/) 20 | 21 | """ 22 | 23 | import markdown 24 | 25 | BR_RE = r'\n' 26 | 27 | class Nl2BrExtension(markdown.Extension): 28 | 29 | def extendMarkdown(self, md, md_globals): 30 | br_tag = markdown.inlinepatterns.SubstituteTagPattern(BR_RE, 'br') 31 | md.inlinePatterns.add('nl', br_tag, '_end') 32 | 33 | 34 | def makeExtension(configs=None): 35 | return Nl2BrExtension(configs) 36 | 37 | -------------------------------------------------------------------------------- /third_party/markdown/extensions/sane_lists.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Sane List Extension for Python-Markdown 4 | ======================================= 5 | 6 | Modify the behavior of Lists in Python-Markdown t act in a sane manor. 7 | 8 | In standard Markdown sytex, the following would constitute a single 9 | ordered list. However, with this extension, the output would include 10 | two lists, the first an ordered list and the second and unordered list. 11 | 12 | 1. ordered 13 | 2. list 14 | 15 | * unordered 16 | * list 17 | 18 | Copyright 2011 - [Waylan Limberg](http://achinghead.com) 19 | 20 | """ 21 | 22 | import re 23 | import markdown 24 | 25 | 26 | class SaneOListProcessor(markdown.blockprocessors.OListProcessor): 27 | 28 | CHILD_RE = re.compile(r'^[ ]{0,3}((\d+\.))[ ]+(.*)') 29 | SIBLING_TAGS = ['ol'] 30 | 31 | 32 | class SaneUListProcessor(markdown.blockprocessors.UListProcessor): 33 | 34 | CHILD_RE = re.compile(r'^[ ]{0,3}(([*+-]))[ ]+(.*)') 35 | SIBLING_TAGS = ['ul'] 36 | 37 | 38 | class SaneListExtension(markdown.Extension): 39 | """ Add sane lists to Markdown. """ 40 | 41 | def extendMarkdown(self, md, md_globals): 42 | """ Override existing Processors. """ 43 | md.parser.blockprocessors['olist'] = SaneOListProcessor(md.parser) 44 | md.parser.blockprocessors['ulist'] = SaneUListProcessor(md.parser) 45 | 46 | 47 | def makeExtension(configs={}): 48 | return SaneListExtension(configs=configs) 49 | 50 | -------------------------------------------------------------------------------- /third_party/markdown/extensions/smart_strong.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Smart_Strong Extension for Python-Markdown 3 | ========================================== 4 | 5 | This extention adds smarter handling of double underscores within words. 6 | 7 | Simple Usage: 8 | 9 | >>> import markdown 10 | >>> print markdown.markdown('Text with double__underscore__words.', 11 | ... extensions=['smart_strong']) 12 |

Text with double__underscore__words.

13 | >>> print markdown.markdown('__Strong__ still works.', 14 | ... extensions=['smart_strong']) 15 |

Strong still works.

16 | >>> print markdown.markdown('__this__works__too__.', 17 | ... extensions=['smart_strong']) 18 |

this__works__too.

19 | 20 | Copyright 2011 21 | [Waylan Limberg](http://achinghead.com) 22 | 23 | ''' 24 | 25 | import re 26 | import markdown 27 | from markdown.inlinepatterns import SimpleTagPattern 28 | 29 | SMART_STRONG_RE = r'(?emphasis2') 39 | 40 | def makeExtension(configs={}): 41 | return SmartEmphasisExtension(configs=dict(configs)) 42 | 43 | if __name__ == '__main__': 44 | import doctest 45 | doctest.testmod() 46 | -------------------------------------------------------------------------------- /third_party/mdx_gfm/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012, the Dart project authors. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above 8 | copyright notice, this list of conditions and the following 9 | disclaimer in the documentation and/or other materials provided 10 | with the distribution. 11 | * Neither the name of Google Inc. nor the names of its 12 | contributors may be used to endorse or promote products derived 13 | from this software without specific prior written permission. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /third_party/mdx_gfm/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from markdown.extensions.nl2br import Nl2BrExtension 6 | 7 | from mdx_partial_gfm import PartialGithubFlavoredMarkdownExtension 8 | 9 | def makeExtension(configs=None): 10 | return GithubFlavoredMarkdownExtension(configs=configs) 11 | 12 | class GithubFlavoredMarkdownExtension(PartialGithubFlavoredMarkdownExtension): 13 | """An extension that's as compatible as possible with GFM. 14 | 15 | This extension aims to be compatible with the standard GFM that GitHub uses 16 | for comments and issues. It has all the extensions described in the `GFM 17 | documentation`_, except for intra-Github links to commits, repostiories, and 18 | issues. 19 | 20 | Note that Markdown-formatted gists and files (including READMEs) on GitHub 21 | use a slightly different variant of GFM. For that, use 22 | :class:`~mdx_partial_gfm.PartialGithubFlavoredMarkdownExtension`. 23 | """ 24 | 25 | def extendMarkdown(self, md, md_globals): 26 | PartialGithubFlavoredMarkdownExtension.extendMarkdown(self, md, md_globals) 27 | 28 | Nl2BrExtension().extendMarkdown(md, md_globals) 29 | -------------------------------------------------------------------------------- /third_party/mdx_partial_gfm/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012, the Dart project authors. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above 8 | copyright notice, this list of conditions and the following 9 | disclaimer in the documentation and/or other materials provided 10 | with the distribution. 11 | * Neither the name of Google Inc. nor the names of its 12 | contributors may be used to endorse or promote products derived 13 | from this software without specific prior written permission. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /third_party/mdx_partial_gfm/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | from markdown.extensions import Extension 6 | from markdown.extensions.fenced_code import FencedCodeExtension 7 | from markdown.extensions.smart_strong import SmartEmphasisExtension 8 | from markdown.extensions.tables import TableExtension 9 | 10 | import gfm 11 | 12 | def makeExtension(configs=None): 13 | return PartialGithubFlavoredMarkdownExtension(configs=configs) 14 | 15 | class PartialGithubFlavoredMarkdownExtension(Extension): 16 | """An extension that's as compatible as possible with GFM. 17 | 18 | This extension aims to be compatible with the variant of GFM that GitHub 19 | uses for Markdown-formatted gists and files (including READMEs). This 20 | variant seems to have all the extensions described in the `GFM 21 | documentation`_, except: 22 | 23 | - Newlines in paragraphs are not transformed into ``br`` tags. 24 | - Intra-Github links to commits, repositories, and issues are not supported. 25 | 26 | .. _the GFM documentation: http://github.github.com/github-flavored-markdown 27 | """ 28 | 29 | def extendMarkdown(self, md, md_globals): 30 | # Built-in extensions 31 | FencedCodeExtension().extendMarkdown(md, md_globals) 32 | SmartEmphasisExtension().extendMarkdown(md, md_globals) 33 | TableExtension().extendMarkdown(md, md_globals) 34 | 35 | # Custom extensions 36 | gfm.AutolinkExtension().extendMarkdown(md, md_globals) 37 | gfm.AutomailExtension().extendMarkdown(md, md_globals) 38 | gfm.HiddenHiliteExtension([ 39 | ('guess_lang', 'False'), 40 | ('css_class', 'highlight') 41 | ]).extendMarkdown(md, md_globals) 42 | gfm.SemiSaneListExtension().extendMarkdown(md, md_globals) 43 | -------------------------------------------------------------------------------- /third_party/oauth2client/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "1.2" 2 | 3 | GOOGLE_AUTH_URI = 'https://accounts.google.com/o/oauth2/auth' 4 | GOOGLE_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke' 5 | GOOGLE_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token' 6 | -------------------------------------------------------------------------------- /third_party/oauth2client/anyjson.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Utility module to import a JSON module 16 | 17 | Hides all the messy details of exactly where 18 | we get a simplejson module from. 19 | """ 20 | 21 | __author__ = 'jcgregorio@google.com (Joe Gregorio)' 22 | 23 | 24 | try: # pragma: no cover 25 | # Should work for Python2.6 and higher. 26 | import json as simplejson 27 | except ImportError: # pragma: no cover 28 | try: 29 | import simplejson 30 | except ImportError: 31 | # Try to import from django, should work on App Engine 32 | from django.utils import simplejson 33 | -------------------------------------------------------------------------------- /third_party/pygments/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2011 by the respective authors (see AUTHORS file). 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /third_party/pygments/console.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.console 4 | ~~~~~~~~~~~~~~~~ 5 | 6 | Format colored console output. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | esc = "\x1b[" 13 | 14 | codes = {} 15 | codes[""] = "" 16 | codes["reset"] = esc + "39;49;00m" 17 | 18 | codes["bold"] = esc + "01m" 19 | codes["faint"] = esc + "02m" 20 | codes["standout"] = esc + "03m" 21 | codes["underline"] = esc + "04m" 22 | codes["blink"] = esc + "05m" 23 | codes["overline"] = esc + "06m" 24 | 25 | dark_colors = ["black", "darkred", "darkgreen", "brown", "darkblue", 26 | "purple", "teal", "lightgray"] 27 | light_colors = ["darkgray", "red", "green", "yellow", "blue", 28 | "fuchsia", "turquoise", "white"] 29 | 30 | x = 30 31 | for d, l in zip(dark_colors, light_colors): 32 | codes[d] = esc + "%im" % x 33 | codes[l] = esc + "%i;01m" % x 34 | x += 1 35 | 36 | del d, l, x 37 | 38 | codes["darkteal"] = codes["turquoise"] 39 | codes["darkyellow"] = codes["brown"] 40 | codes["fuscia"] = codes["fuchsia"] 41 | codes["white"] = codes["bold"] 42 | 43 | 44 | def reset_color(): 45 | return codes["reset"] 46 | 47 | 48 | def colorize(color_key, text): 49 | return codes[color_key] + text + codes["reset"] 50 | 51 | 52 | def ansiformat(attr, text): 53 | """ 54 | Format ``text`` with a color and/or some attributes:: 55 | 56 | color normal color 57 | *color* bold color 58 | _color_ underlined color 59 | +color+ blinking color 60 | """ 61 | result = [] 62 | if attr[:1] == attr[-1:] == '+': 63 | result.append(codes['blink']) 64 | attr = attr[1:-1] 65 | if attr[:1] == attr[-1:] == '*': 66 | result.append(codes['bold']) 67 | attr = attr[1:-1] 68 | if attr[:1] == attr[-1:] == '_': 69 | result.append(codes['underline']) 70 | attr = attr[1:-1] 71 | result.append(codes[attr]) 72 | result.append(text) 73 | result.append(codes['reset']) 74 | return ''.join(result) 75 | -------------------------------------------------------------------------------- /third_party/pygments/filter.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.filter 4 | ~~~~~~~~~~~~~~~ 5 | 6 | Module that implements the default filter. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | 13 | def apply_filters(stream, filters, lexer=None): 14 | """ 15 | Use this method to apply an iterable of filters to 16 | a stream. If lexer is given it's forwarded to the 17 | filter, otherwise the filter receives `None`. 18 | """ 19 | def _apply(filter_, stream): 20 | for token in filter_.filter(lexer, stream): 21 | yield token 22 | for filter_ in filters: 23 | stream = _apply(filter_, stream) 24 | return stream 25 | 26 | 27 | def simplefilter(f): 28 | """ 29 | Decorator that converts a function into a filter:: 30 | 31 | @simplefilter 32 | def lowercase(lexer, stream, options): 33 | for ttype, value in stream: 34 | yield ttype, value.lower() 35 | """ 36 | return type(f.__name__, (FunctionFilter,), { 37 | 'function': f, 38 | '__module__': getattr(f, '__module__'), 39 | '__doc__': f.__doc__ 40 | }) 41 | 42 | 43 | class Filter(object): 44 | """ 45 | Default filter. Subclass this class or use the `simplefilter` 46 | decorator to create own filters. 47 | """ 48 | 49 | def __init__(self, **options): 50 | self.options = options 51 | 52 | def filter(self, lexer, stream): 53 | raise NotImplementedError() 54 | 55 | 56 | class FunctionFilter(Filter): 57 | """ 58 | Abstract class used by `simplefilter` to create simple 59 | function filters on the fly. The `simplefilter` decorator 60 | automatically creates subclasses of this class for 61 | functions passed to it. 62 | """ 63 | function = None 64 | 65 | def __init__(self, **options): 66 | if not hasattr(self, 'function'): 67 | raise TypeError('%r used without bound function' % 68 | self.__class__.__name__) 69 | Filter.__init__(self, **options) 70 | 71 | def filter(self, lexer, stream): 72 | # pylint: disable-msg=E1102 73 | for ttype, value in self.function(lexer, stream, self.options): 74 | yield ttype, value 75 | -------------------------------------------------------------------------------- /third_party/pygments/formatters/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.formatters 4 | ~~~~~~~~~~~~~~~~~~~ 5 | 6 | Pygments formatters. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | import os.path 12 | import fnmatch 13 | 14 | from pygments.formatters._mapping import FORMATTERS 15 | from pygments.plugin import find_plugin_formatters 16 | from pygments.util import ClassNotFound 17 | 18 | ns = globals() 19 | for fcls in FORMATTERS: 20 | ns[fcls.__name__] = fcls 21 | del fcls 22 | 23 | __all__ = ['get_formatter_by_name', 'get_formatter_for_filename', 24 | 'get_all_formatters'] + [cls.__name__ for cls in FORMATTERS] 25 | 26 | 27 | _formatter_alias_cache = {} 28 | _formatter_filename_cache = [] 29 | 30 | def _init_formatter_cache(): 31 | if _formatter_alias_cache: 32 | return 33 | for cls in get_all_formatters(): 34 | for alias in cls.aliases: 35 | _formatter_alias_cache[alias] = cls 36 | for fn in cls.filenames: 37 | _formatter_filename_cache.append((fn, cls)) 38 | 39 | 40 | def find_formatter_class(name): 41 | _init_formatter_cache() 42 | cls = _formatter_alias_cache.get(name, None) 43 | return cls 44 | 45 | 46 | def get_formatter_by_name(name, **options): 47 | _init_formatter_cache() 48 | cls = _formatter_alias_cache.get(name, None) 49 | if not cls: 50 | raise ClassNotFound("No formatter found for name %r" % name) 51 | return cls(**options) 52 | 53 | 54 | def get_formatter_for_filename(fn, **options): 55 | _init_formatter_cache() 56 | fn = os.path.basename(fn) 57 | for pattern, cls in _formatter_filename_cache: 58 | if fnmatch.fnmatch(fn, pattern): 59 | return cls(**options) 60 | raise ClassNotFound("No formatter found for file name %r" % fn) 61 | 62 | 63 | def get_all_formatters(): 64 | """Return a generator for all formatters.""" 65 | for formatter in FORMATTERS: 66 | yield formatter 67 | for _, formatter in find_plugin_formatters(): 68 | yield formatter 69 | -------------------------------------------------------------------------------- /third_party/pygments/plugin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.plugin 4 | ~~~~~~~~~~~~~~~ 5 | 6 | Pygments setuptools plugin interface. The methods defined 7 | here also work if setuptools isn't installed but they just 8 | return nothing. 9 | 10 | lexer plugins:: 11 | 12 | [pygments.lexers] 13 | yourlexer = yourmodule:YourLexer 14 | 15 | formatter plugins:: 16 | 17 | [pygments.formatters] 18 | yourformatter = yourformatter:YourFormatter 19 | /.ext = yourformatter:YourFormatter 20 | 21 | As you can see, you can define extensions for the formatter 22 | with a leading slash. 23 | 24 | syntax plugins:: 25 | 26 | [pygments.styles] 27 | yourstyle = yourstyle:YourStyle 28 | 29 | filter plugin:: 30 | 31 | [pygments.filter] 32 | yourfilter = yourfilter:YourFilter 33 | 34 | 35 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 36 | :license: BSD, see LICENSE for details. 37 | """ 38 | try: 39 | import pkg_resources 40 | except ImportError: 41 | pkg_resources = None 42 | 43 | LEXER_ENTRY_POINT = 'pygments.lexers' 44 | FORMATTER_ENTRY_POINT = 'pygments.formatters' 45 | STYLE_ENTRY_POINT = 'pygments.styles' 46 | FILTER_ENTRY_POINT = 'pygments.filters' 47 | 48 | 49 | def find_plugin_lexers(): 50 | if pkg_resources is None: 51 | return 52 | for entrypoint in pkg_resources.iter_entry_points(LEXER_ENTRY_POINT): 53 | yield entrypoint.load() 54 | 55 | 56 | def find_plugin_formatters(): 57 | if pkg_resources is None: 58 | return 59 | for entrypoint in pkg_resources.iter_entry_points(FORMATTER_ENTRY_POINT): 60 | yield entrypoint.name, entrypoint.load() 61 | 62 | 63 | def find_plugin_styles(): 64 | if pkg_resources is None: 65 | return 66 | for entrypoint in pkg_resources.iter_entry_points(STYLE_ENTRY_POINT): 67 | yield entrypoint.name, entrypoint.load() 68 | 69 | 70 | def find_plugin_filters(): 71 | if pkg_resources is None: 72 | return 73 | for entrypoint in pkg_resources.iter_entry_points(FILTER_ENTRY_POINT): 74 | yield entrypoint.name, entrypoint.load() 75 | -------------------------------------------------------------------------------- /third_party/pygments/styles/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles 4 | ~~~~~~~~~~~~~~~ 5 | 6 | Contains built-in styles. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.plugin import find_plugin_styles 13 | from pygments.util import ClassNotFound 14 | 15 | 16 | #: Maps style names to 'submodule::classname'. 17 | STYLE_MAP = { 18 | 'default': 'default::DefaultStyle', 19 | 'emacs': 'emacs::EmacsStyle', 20 | 'friendly': 'friendly::FriendlyStyle', 21 | 'colorful': 'colorful::ColorfulStyle', 22 | 'autumn': 'autumn::AutumnStyle', 23 | 'murphy': 'murphy::MurphyStyle', 24 | 'manni': 'manni::ManniStyle', 25 | 'monokai': 'monokai::MonokaiStyle', 26 | 'perldoc': 'perldoc::PerldocStyle', 27 | 'pastie': 'pastie::PastieStyle', 28 | 'borland': 'borland::BorlandStyle', 29 | 'trac': 'trac::TracStyle', 30 | 'native': 'native::NativeStyle', 31 | 'fruity': 'fruity::FruityStyle', 32 | 'bw': 'bw::BlackWhiteStyle', 33 | 'vim': 'vim::VimStyle', 34 | 'vs': 'vs::VisualStudioStyle', 35 | 'tango': 'tango::TangoStyle', 36 | 'rrt': 'rrt::RrtStyle', 37 | } 38 | 39 | 40 | def get_style_by_name(name): 41 | if name in STYLE_MAP: 42 | mod, cls = STYLE_MAP[name].split('::') 43 | builtin = "yes" 44 | else: 45 | for found_name, style in find_plugin_styles(): 46 | if name == found_name: 47 | return style 48 | # perhaps it got dropped into our styles package 49 | builtin = "" 50 | mod = name 51 | cls = name.title() + "Style" 52 | 53 | try: 54 | mod = __import__('pygments.styles.' + mod, None, None, [cls]) 55 | except ImportError: 56 | raise ClassNotFound("Could not find style module %r" % mod + 57 | (builtin and ", though it should be builtin") + ".") 58 | try: 59 | return getattr(mod, cls) 60 | except AttributeError: 61 | raise ClassNotFound("Could not find style class %r in style module." % cls) 62 | 63 | 64 | def get_all_styles(): 65 | """Return an generator for all styles by name, 66 | both builtin and plugin.""" 67 | for name in STYLE_MAP: 68 | yield name 69 | for name, _ in find_plugin_styles(): 70 | yield name 71 | -------------------------------------------------------------------------------- /third_party/pygments/styles/autumn.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.autumn 4 | ~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | A colorful style, inspired by the terminal highlighting style. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Number, Operator, Generic, Whitespace 15 | 16 | 17 | class AutumnStyle(Style): 18 | """ 19 | A colorful style, inspired by the terminal highlighting style. 20 | """ 21 | 22 | default_style = "" 23 | 24 | styles = { 25 | Whitespace: '#bbbbbb', 26 | 27 | Comment: 'italic #aaaaaa', 28 | Comment.Preproc: 'noitalic #4c8317', 29 | Comment.Special: 'italic #0000aa', 30 | 31 | Keyword: '#0000aa', 32 | Keyword.Type: '#00aaaa', 33 | 34 | Operator.Word: '#0000aa', 35 | 36 | Name.Builtin: '#00aaaa', 37 | Name.Function: '#00aa00', 38 | Name.Class: 'underline #00aa00', 39 | Name.Namespace: 'underline #00aaaa', 40 | Name.Variable: '#aa0000', 41 | Name.Constant: '#aa0000', 42 | Name.Entity: 'bold #800', 43 | Name.Attribute: '#1e90ff', 44 | Name.Tag: 'bold #1e90ff', 45 | Name.Decorator: '#888888', 46 | 47 | String: '#aa5500', 48 | String.Symbol: '#0000aa', 49 | String.Regex: '#009999', 50 | 51 | Number: '#009999', 52 | 53 | Generic.Heading: 'bold #000080', 54 | Generic.Subheading: 'bold #800080', 55 | Generic.Deleted: '#aa0000', 56 | Generic.Inserted: '#00aa00', 57 | Generic.Error: '#aa0000', 58 | Generic.Emph: 'italic', 59 | Generic.Strong: 'bold', 60 | Generic.Prompt: '#555555', 61 | Generic.Output: '#888888', 62 | Generic.Traceback: '#aa0000', 63 | 64 | Error: '#F00 bg:#FAA' 65 | } 66 | -------------------------------------------------------------------------------- /third_party/pygments/styles/borland.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.borland 4 | ~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | Style similar to the style used in the Borland IDEs. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Number, Operator, Generic, Whitespace 15 | 16 | 17 | class BorlandStyle(Style): 18 | """ 19 | Style similar to the style used in the borland IDEs. 20 | """ 21 | 22 | default_style = '' 23 | 24 | styles = { 25 | Whitespace: '#bbbbbb', 26 | 27 | Comment: 'italic #008800', 28 | Comment.Preproc: 'noitalic #008080', 29 | Comment.Special: 'noitalic bold', 30 | 31 | String: '#0000FF', 32 | String.Char: '#800080', 33 | Number: '#0000FF', 34 | Keyword: 'bold #000080', 35 | Operator.Word: 'bold', 36 | Name.Tag: 'bold #000080', 37 | Name.Attribute: '#FF0000', 38 | 39 | Generic.Heading: '#999999', 40 | Generic.Subheading: '#aaaaaa', 41 | Generic.Deleted: 'bg:#ffdddd #000000', 42 | Generic.Inserted: 'bg:#ddffdd #000000', 43 | Generic.Error: '#aa0000', 44 | Generic.Emph: 'italic', 45 | Generic.Strong: 'bold', 46 | Generic.Prompt: '#555555', 47 | Generic.Output: '#888888', 48 | Generic.Traceback: '#aa0000', 49 | 50 | Error: 'bg:#e3d2d2 #a61717' 51 | } 52 | -------------------------------------------------------------------------------- /third_party/pygments/styles/bw.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.bw 4 | ~~~~~~~~~~~~~~~~~~ 5 | 6 | Simple black/white only style. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Operator, Generic 15 | 16 | 17 | class BlackWhiteStyle(Style): 18 | 19 | background_color = "#ffffff" 20 | default_style = "" 21 | 22 | styles = { 23 | Comment: "italic", 24 | Comment.Preproc: "noitalic", 25 | 26 | Keyword: "bold", 27 | Keyword.Pseudo: "nobold", 28 | Keyword.Type: "nobold", 29 | 30 | Operator.Word: "bold", 31 | 32 | Name.Class: "bold", 33 | Name.Namespace: "bold", 34 | Name.Exception: "bold", 35 | Name.Entity: "bold", 36 | Name.Tag: "bold", 37 | 38 | String: "italic", 39 | String.Interpol: "bold", 40 | String.Escape: "bold", 41 | 42 | Generic.Heading: "bold", 43 | Generic.Subheading: "bold", 44 | Generic.Emph: "italic", 45 | Generic.Strong: "bold", 46 | Generic.Prompt: "bold", 47 | 48 | Error: "border:#FF0000" 49 | } 50 | -------------------------------------------------------------------------------- /third_party/pygments/styles/fruity.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.fruity 4 | ~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | pygments version of my "fruity" vim theme. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Token, Comment, Name, Keyword, \ 14 | Generic, Number, String, Whitespace 15 | 16 | class FruityStyle(Style): 17 | """ 18 | Pygments version of the "native" vim theme. 19 | """ 20 | 21 | background_color = '#111111' 22 | highlight_color = '#333333' 23 | 24 | styles = { 25 | Whitespace: '#888888', 26 | Token: '#ffffff', 27 | Generic.Output: '#444444 bg:#222222', 28 | Keyword: '#fb660a bold', 29 | Keyword.Pseudo: 'nobold', 30 | Number: '#0086f7 bold', 31 | Name.Tag: '#fb660a bold', 32 | Name.Variable: '#fb660a', 33 | Comment: '#008800 bg:#0f140f italic', 34 | Name.Attribute: '#ff0086 bold', 35 | String: '#0086d2', 36 | Name.Function: '#ff0086 bold', 37 | Generic.Heading: '#ffffff bold', 38 | Keyword.Type: '#cdcaa9 bold', 39 | Generic.Subheading: '#ffffff bold', 40 | Name.Constant: '#0086d2', 41 | Comment.Preproc: '#ff0007 bold' 42 | } 43 | -------------------------------------------------------------------------------- /third_party/pygments/styles/manni.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.manni 4 | ~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | A colorful style, inspired by the terminal highlighting style. 7 | 8 | This is a port of the style used in the `php port`_ of pygments 9 | by Manni. The style is called 'default' there. 10 | 11 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 12 | :license: BSD, see LICENSE for details. 13 | """ 14 | 15 | from pygments.style import Style 16 | from pygments.token import Keyword, Name, Comment, String, Error, \ 17 | Number, Operator, Generic, Whitespace 18 | 19 | 20 | class ManniStyle(Style): 21 | """ 22 | A colorful style, inspired by the terminal highlighting style. 23 | """ 24 | 25 | background_color = '#f0f3f3' 26 | 27 | styles = { 28 | Whitespace: '#bbbbbb', 29 | Comment: 'italic #0099FF', 30 | Comment.Preproc: 'noitalic #009999', 31 | Comment.Special: 'bold', 32 | 33 | Keyword: 'bold #006699', 34 | Keyword.Pseudo: 'nobold', 35 | Keyword.Type: '#007788', 36 | 37 | Operator: '#555555', 38 | Operator.Word: 'bold #000000', 39 | 40 | Name.Builtin: '#336666', 41 | Name.Function: '#CC00FF', 42 | Name.Class: 'bold #00AA88', 43 | Name.Namespace: 'bold #00CCFF', 44 | Name.Exception: 'bold #CC0000', 45 | Name.Variable: '#003333', 46 | Name.Constant: '#336600', 47 | Name.Label: '#9999FF', 48 | Name.Entity: 'bold #999999', 49 | Name.Attribute: '#330099', 50 | Name.Tag: 'bold #330099', 51 | Name.Decorator: '#9999FF', 52 | 53 | String: '#CC3300', 54 | String.Doc: 'italic', 55 | String.Interpol: '#AA0000', 56 | String.Escape: 'bold #CC3300', 57 | String.Regex: '#33AAAA', 58 | String.Symbol: '#FFCC33', 59 | String.Other: '#CC3300', 60 | 61 | Number: '#FF6600', 62 | 63 | Generic.Heading: 'bold #003300', 64 | Generic.Subheading: 'bold #003300', 65 | Generic.Deleted: 'border:#CC0000 bg:#FFCCCC', 66 | Generic.Inserted: 'border:#00CC00 bg:#CCFFCC', 67 | Generic.Error: '#FF0000', 68 | Generic.Emph: 'italic', 69 | Generic.Strong: 'bold', 70 | Generic.Prompt: 'bold #000099', 71 | Generic.Output: '#AAAAAA', 72 | Generic.Traceback: '#99CC66', 73 | 74 | Error: 'bg:#FFAAAA #AA0000' 75 | } 76 | -------------------------------------------------------------------------------- /third_party/pygments/styles/native.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.native 4 | ~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | pygments version of my "native" vim theme. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Number, Operator, Generic, Token, Whitespace 15 | 16 | 17 | class NativeStyle(Style): 18 | """ 19 | Pygments version of the "native" vim theme. 20 | """ 21 | 22 | background_color = '#202020' 23 | highlight_color = '#404040' 24 | 25 | styles = { 26 | Token: '#d0d0d0', 27 | Whitespace: '#666666', 28 | 29 | Comment: 'italic #999999', 30 | Comment.Preproc: 'noitalic bold #cd2828', 31 | Comment.Special: 'noitalic bold #e50808 bg:#520000', 32 | 33 | Keyword: 'bold #6ab825', 34 | Keyword.Pseudo: 'nobold', 35 | Operator.Word: 'bold #6ab825', 36 | 37 | String: '#ed9d13', 38 | String.Other: '#ffa500', 39 | 40 | Number: '#3677a9', 41 | 42 | Name.Builtin: '#24909d', 43 | Name.Variable: '#40ffff', 44 | Name.Constant: '#40ffff', 45 | Name.Class: 'underline #447fcf', 46 | Name.Function: '#447fcf', 47 | Name.Namespace: 'underline #447fcf', 48 | Name.Exception: '#bbbbbb', 49 | Name.Tag: 'bold #6ab825', 50 | Name.Attribute: '#bbbbbb', 51 | Name.Decorator: '#ffa500', 52 | 53 | Generic.Heading: 'bold #ffffff', 54 | Generic.Subheading: 'underline #ffffff', 55 | Generic.Deleted: '#d22323', 56 | Generic.Inserted: '#589819', 57 | Generic.Error: '#d22323', 58 | Generic.Emph: 'italic', 59 | Generic.Strong: 'bold', 60 | Generic.Prompt: '#aaaaaa', 61 | Generic.Output: '#cccccc', 62 | Generic.Traceback: '#d22323', 63 | 64 | Error: 'bg:#e3d2d2 #a61717' 65 | } 66 | -------------------------------------------------------------------------------- /third_party/pygments/styles/perldoc.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.perldoc 4 | ~~~~~~~~~~~~~~~~~~~~~~~ 5 | 6 | Style similar to the style used in the `perldoc`_ code blocks. 7 | 8 | .. _perldoc: http://perldoc.perl.org/ 9 | 10 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 11 | :license: BSD, see LICENSE for details. 12 | """ 13 | 14 | from pygments.style import Style 15 | from pygments.token import Keyword, Name, Comment, String, Error, \ 16 | Number, Operator, Generic, Whitespace 17 | 18 | 19 | class PerldocStyle(Style): 20 | """ 21 | Style similar to the style used in the perldoc code blocks. 22 | """ 23 | 24 | background_color = '#eeeedd' 25 | default_style = '' 26 | 27 | styles = { 28 | Whitespace: '#bbbbbb', 29 | Comment: '#228B22', 30 | Comment.Preproc: '#1e889b', 31 | Comment.Special: '#8B008B bold', 32 | 33 | String: '#CD5555', 34 | String.Heredoc: '#1c7e71 italic', 35 | String.Regex: '#B452CD', 36 | String.Other: '#cb6c20', 37 | String.Regex: '#1c7e71', 38 | 39 | Number: '#B452CD', 40 | 41 | Operator.Word: '#8B008B', 42 | 43 | Keyword: '#8B008B bold', 44 | Keyword.Type: '#a7a7a7', 45 | 46 | Name.Class: '#008b45 bold', 47 | Name.Exception: '#008b45 bold', 48 | Name.Function: '#008b45', 49 | Name.Namespace: '#008b45 underline', 50 | Name.Variable: '#00688B', 51 | Name.Constant: '#00688B', 52 | Name.Decorator: '#707a7c', 53 | Name.Tag: '#8B008B bold', 54 | Name.Attribute: '#658b00', 55 | Name.Builtin: '#658b00', 56 | 57 | Generic.Heading: 'bold #000080', 58 | Generic.Subheading: 'bold #800080', 59 | Generic.Deleted: '#aa0000', 60 | Generic.Inserted: '#00aa00', 61 | Generic.Error: '#aa0000', 62 | Generic.Emph: 'italic', 63 | Generic.Strong: 'bold', 64 | Generic.Prompt: '#555555', 65 | Generic.Output: '#888888', 66 | Generic.Traceback: '#aa0000', 67 | 68 | Error: 'bg:#e3d2d2 #a61717' 69 | } 70 | -------------------------------------------------------------------------------- /third_party/pygments/styles/rrt.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.rrt 4 | ~~~~~~~~~~~~~~~~~~~ 5 | 6 | pygments "rrt" theme, based on Zap and Emacs defaults. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Comment, Name, Keyword, String 14 | 15 | 16 | class RrtStyle(Style): 17 | """ 18 | Minimalistic "rrt" theme, based on Zap and Emacs defaults. 19 | """ 20 | 21 | background_color = '#000000' 22 | highlight_color = '#0000ff' 23 | 24 | styles = { 25 | Comment: '#00ff00', 26 | Name.Function: '#ffff00', 27 | Name.Variable: '#eedd82', 28 | Name.Constant: '#7fffd4', 29 | Keyword: '#ff0000', 30 | Comment.Preproc: '#e5e5e5', 31 | String: '#87ceeb', 32 | Keyword.Type: '#ee82ee', 33 | } 34 | -------------------------------------------------------------------------------- /third_party/pygments/styles/trac.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.trac 4 | ~~~~~~~~~~~~~~~~~~~~ 5 | 6 | Port of the default trac highlighter design. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Number, Operator, Generic, Whitespace 15 | 16 | 17 | class TracStyle(Style): 18 | """ 19 | Port of the default trac highlighter design. 20 | """ 21 | 22 | default_style = '' 23 | 24 | styles = { 25 | Whitespace: '#bbbbbb', 26 | Comment: 'italic #999988', 27 | Comment.Preproc: 'bold noitalic #999999', 28 | Comment.Special: 'bold #999999', 29 | 30 | Operator: 'bold', 31 | 32 | String: '#bb8844', 33 | String.Regex: '#808000', 34 | 35 | Number: '#009999', 36 | 37 | Keyword: 'bold', 38 | Keyword.Type: '#445588', 39 | 40 | Name.Builtin: '#999999', 41 | Name.Function: 'bold #990000', 42 | Name.Class: 'bold #445588', 43 | Name.Exception: 'bold #990000', 44 | Name.Namespace: '#555555', 45 | Name.Variable: '#008080', 46 | Name.Constant: '#008080', 47 | Name.Tag: '#000080', 48 | Name.Attribute: '#008080', 49 | Name.Entity: '#800080', 50 | 51 | Generic.Heading: '#999999', 52 | Generic.Subheading: '#aaaaaa', 53 | Generic.Deleted: 'bg:#ffdddd #000000', 54 | Generic.Inserted: 'bg:#ddffdd #000000', 55 | Generic.Error: '#aa0000', 56 | Generic.Emph: 'italic', 57 | Generic.Strong: 'bold', 58 | Generic.Prompt: '#555555', 59 | Generic.Output: '#888888', 60 | Generic.Traceback: '#aa0000', 61 | 62 | Error: 'bg:#e3d2d2 #a61717' 63 | } 64 | -------------------------------------------------------------------------------- /third_party/pygments/styles/vim.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.vim 4 | ~~~~~~~~~~~~~~~~~~~ 5 | 6 | A highlighting style for Pygments, inspired by vim. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Number, Operator, Generic, Whitespace, Token 15 | 16 | 17 | class VimStyle(Style): 18 | """ 19 | Styles somewhat like vim 7.0 20 | """ 21 | 22 | background_color = "#000000" 23 | highlight_color = "#222222" 24 | default_style = "#cccccc" 25 | 26 | styles = { 27 | Token: "#cccccc", 28 | Whitespace: "", 29 | Comment: "#000080", 30 | Comment.Preproc: "", 31 | Comment.Special: "bold #cd0000", 32 | 33 | Keyword: "#cdcd00", 34 | Keyword.Declaration: "#00cd00", 35 | Keyword.Namespace: "#cd00cd", 36 | Keyword.Pseudo: "", 37 | Keyword.Type: "#00cd00", 38 | 39 | Operator: "#3399cc", 40 | Operator.Word: "#cdcd00", 41 | 42 | Name: "", 43 | Name.Class: "#00cdcd", 44 | Name.Builtin: "#cd00cd", 45 | Name.Exception: "bold #666699", 46 | Name.Variable: "#00cdcd", 47 | 48 | String: "#cd0000", 49 | Number: "#cd00cd", 50 | 51 | Generic.Heading: "bold #000080", 52 | Generic.Subheading: "bold #800080", 53 | Generic.Deleted: "#cd0000", 54 | Generic.Inserted: "#00cd00", 55 | Generic.Error: "#FF0000", 56 | Generic.Emph: "italic", 57 | Generic.Strong: "bold", 58 | Generic.Prompt: "bold #000080", 59 | Generic.Output: "#888", 60 | Generic.Traceback: "#04D", 61 | 62 | Error: "border:#FF0000" 63 | } 64 | -------------------------------------------------------------------------------- /third_party/pygments/styles/vs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pygments.styles.vs 4 | ~~~~~~~~~~~~~~~~~~ 5 | 6 | Simple style with MS Visual Studio colors. 7 | 8 | :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS. 9 | :license: BSD, see LICENSE for details. 10 | """ 11 | 12 | from pygments.style import Style 13 | from pygments.token import Keyword, Name, Comment, String, Error, \ 14 | Operator, Generic 15 | 16 | 17 | class VisualStudioStyle(Style): 18 | 19 | background_color = "#ffffff" 20 | default_style = "" 21 | 22 | styles = { 23 | Comment: "#008000", 24 | Comment.Preproc: "#0000ff", 25 | Keyword: "#0000ff", 26 | Operator.Word: "#0000ff", 27 | Keyword.Type: "#2b91af", 28 | Name.Class: "#2b91af", 29 | String: "#a31515", 30 | 31 | Generic.Heading: "bold", 32 | Generic.Subheading: "bold", 33 | Generic.Emph: "italic", 34 | Generic.Strong: "bold", 35 | Generic.Prompt: "bold", 36 | 37 | Error: "border:#FF0000" 38 | } 39 | -------------------------------------------------------------------------------- /third_party/pystache/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Chris Jerdonek. All rights reserved. 2 | Copyright (c) 2009 Chris Wanstrath 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /third_party/pystache/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | # We keep all initialization code in a separate module. 8 | 9 | from pystache.init import render, Renderer, TemplateSpec 10 | 11 | __all__ = ['render', 'Renderer', 'TemplateSpec'] 12 | 13 | __version__ = '0.5.2' # Also change in setup.py. 14 | -------------------------------------------------------------------------------- /third_party/pystache/commands/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: add a docstring. 3 | 4 | """ 5 | -------------------------------------------------------------------------------- /third_party/pystache/commands/test.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | This module provides a command to test pystache (unit tests, doctests, etc). 5 | 6 | """ 7 | 8 | import sys 9 | 10 | from pystache.tests.main import main as run_tests 11 | 12 | 13 | def main(sys_argv=sys.argv): 14 | run_tests(sys_argv=sys_argv) 15 | 16 | 17 | if __name__=='__main__': 18 | main() 19 | -------------------------------------------------------------------------------- /third_party/pystache/common.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Exposes functionality needed throughout the project. 5 | 6 | """ 7 | 8 | # This function was designed to be portable across Python versions -- both 9 | # with older versions and with Python 3 after applying 2to3. 10 | def read(path): 11 | """ 12 | Return the contents of a text file as a byte string. 13 | 14 | """ 15 | # Opening in binary mode is necessary for compatibility across Python 16 | # 2 and 3. In both Python 2 and 3, open() defaults to opening files in 17 | # text mode. However, in Python 2, open() returns file objects whose 18 | # read() method returns byte strings (strings of type `str` in Python 2), 19 | # whereas in Python 3, the file object returns unicode strings (strings 20 | # of type `str` in Python 3). 21 | f = open(path, 'rb') 22 | # We avoid use of the with keyword for Python 2.4 support. 23 | try: 24 | return f.read() 25 | finally: 26 | f.close() 27 | 28 | 29 | class PystacheError(Exception): 30 | """Base class for Pystache exceptions.""" 31 | pass 32 | 33 | 34 | class TemplateNotFoundError(PystacheError): 35 | """An exception raised when a template is not found.""" 36 | pass 37 | -------------------------------------------------------------------------------- /third_party/pystache/defaults.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | This module provides a central location for defining default behavior. 5 | 6 | Throughout the package, these defaults take effect only when the user 7 | does not otherwise specify a value. 8 | 9 | """ 10 | 11 | try: 12 | # Python 3.2 adds html.escape() and deprecates cgi.escape(). 13 | from html import escape 14 | except ImportError: 15 | from cgi import escape 16 | 17 | import os 18 | import sys 19 | 20 | 21 | # How to handle encoding errors when decoding strings from str to unicode. 22 | # 23 | # This value is passed as the "errors" argument to Python's built-in 24 | # unicode() function: 25 | # 26 | # http://docs.python.org/library/functions.html#unicode 27 | # 28 | DECODE_ERRORS = 'strict' 29 | 30 | # The name of the encoding to use when converting to unicode any strings of 31 | # type str encountered during the rendering process. 32 | STRING_ENCODING = sys.getdefaultencoding() 33 | 34 | # The name of the encoding to use when converting file contents to unicode. 35 | # This default takes precedence over the STRING_ENCODING default for 36 | # strings that arise from files. 37 | FILE_ENCODING = sys.getdefaultencoding() 38 | 39 | # The starting list of directories in which to search for templates when 40 | # loading a template by file name. 41 | SEARCH_DIRS = [os.curdir] # i.e. ['.'] 42 | 43 | # The escape function to apply to strings that require escaping when 44 | # rendering templates (e.g. for tags enclosed in double braces). 45 | # Only unicode strings will be passed to this function. 46 | # 47 | # The quote=True argument causes double but not single quotes to be escaped 48 | # in Python 3.1 and earlier, and both double and single quotes to be 49 | # escaped in Python 3.2 and later: 50 | # 51 | # http://docs.python.org/library/cgi.html#cgi.escape 52 | # http://docs.python.org/dev/library/html.html#html.escape 53 | # 54 | TAG_ESCAPE = lambda u: escape(u, quote=True) 55 | 56 | # The default template extension. 57 | TEMPLATE_EXTENSION = 'mustache' 58 | -------------------------------------------------------------------------------- /third_party/pystache/init.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | """ 4 | This module contains the initialization logic called by __init__.py. 5 | 6 | """ 7 | 8 | from pystache.renderer import Renderer 9 | from pystache.template_spec import TemplateSpec 10 | 11 | 12 | def render(template, context=None, **kwargs): 13 | """ 14 | Return the given template string rendered using the given context. 15 | 16 | """ 17 | renderer = Renderer() 18 | return renderer.render(template, context, **kwargs) 19 | -------------------------------------------------------------------------------- /third_party/pystache/parsed.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Exposes a class that represents a parsed (or compiled) template. 5 | 6 | This module is meant only for internal use. 7 | 8 | """ 9 | 10 | 11 | class ParsedTemplate(object): 12 | 13 | def __init__(self, parse_tree): 14 | """ 15 | Arguments: 16 | 17 | parse_tree: a list, each element of which is either-- 18 | 19 | (1) a unicode string, or 20 | (2) a "rendering" callable that accepts a ContextStack instance 21 | and returns a unicode string. 22 | 23 | The possible rendering callables are the return values of the 24 | following functions: 25 | 26 | * RenderEngine._make_get_escaped() 27 | * RenderEngine._make_get_inverse() 28 | * RenderEngine._make_get_literal() 29 | * RenderEngine._make_get_partial() 30 | * RenderEngine._make_get_section() 31 | 32 | """ 33 | self._parse_tree = parse_tree 34 | 35 | def __repr__(self): 36 | return "[%s]" % (", ".join([repr(part) for part in self._parse_tree])) 37 | 38 | def render(self, context): 39 | """ 40 | Returns: a string of type unicode. 41 | 42 | """ 43 | # We avoid use of the ternary operator for Python 2.4 support. 44 | def get_unicode(val): 45 | if callable(val): 46 | return val(context) 47 | return val 48 | parts = map(get_unicode, self._parse_tree) 49 | s = ''.join(parts) 50 | 51 | return unicode(s) 52 | 53 | -------------------------------------------------------------------------------- /third_party/pystache/template_spec.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Provides a class to customize template information on a per-view basis. 5 | 6 | To customize template properties for a particular view, create that view 7 | from a class that subclasses TemplateSpec. The "Spec" in TemplateSpec 8 | stands for template information that is "special" or "specified". 9 | 10 | """ 11 | 12 | # TODO: finish the class docstring. 13 | class TemplateSpec(object): 14 | 15 | """ 16 | A mixin or interface for specifying custom template information. 17 | 18 | The "spec" in TemplateSpec can be taken to mean that the template 19 | information is either "specified" or "special." 20 | 21 | A view should subclass this class only if customized template loading 22 | is needed. The following attributes allow one to customize/override 23 | template information on a per view basis. A None value means to use 24 | default behavior for that value and perform no customization. All 25 | attributes are initialized to None. 26 | 27 | Attributes: 28 | 29 | template: the template as a string. 30 | 31 | template_rel_path: the path to the template file, relative to the 32 | directory containing the module defining the class. 33 | 34 | template_rel_directory: the directory containing the template file, relative 35 | to the directory containing the module defining the class. 36 | 37 | template_extension: the template file extension. Defaults to "mustache". 38 | Pass False for no extension (i.e. extensionless template files). 39 | 40 | """ 41 | 42 | template = None 43 | template_rel_path = None 44 | template_rel_directory = None 45 | template_name = None 46 | template_extension = None 47 | template_encoding = None 48 | -------------------------------------------------------------------------------- /third_party/pystache/tests/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: add a docstring. 3 | 4 | """ 5 | -------------------------------------------------------------------------------- /third_party/pystache/tests/benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | """ 5 | A rudimentary backward- and forward-compatible script to benchmark pystache. 6 | 7 | Usage: 8 | 9 | tests/benchmark.py 10000 10 | 11 | """ 12 | 13 | import sys 14 | from timeit import Timer 15 | 16 | import pystache 17 | 18 | # TODO: make the example realistic. 19 | 20 | examples = [ 21 | # Test case: 1 22 | ("""{{#person}}Hi {{name}}{{/person}}""", 23 | {"person": {"name": "Jon"}}, 24 | "Hi Jon"), 25 | 26 | # Test case: 2 27 | ("""\ 28 |
29 |

{{header}}

30 |
    31 | {{#comments}}
  • 32 |
    {{name}}

    {{body}}

    33 |
  • {{/comments}} 34 |
35 |
""", 36 | {'header': "My Post Comments", 37 | 'comments': [ 38 | {'name': "Joe", 'body': "Thanks for this post!"}, 39 | {'name': "Sam", 'body': "Thanks for this post!"}, 40 | {'name': "Heather", 'body': "Thanks for this post!"}, 41 | {'name': "Kathy", 'body': "Thanks for this post!"}, 42 | {'name': "George", 'body': "Thanks for this post!"}]}, 43 | """\ 44 |
45 |

My Post Comments

46 |
    47 |
  • 48 |
    Joe

    Thanks for this post!

    49 |
  • 50 |
    Sam

    Thanks for this post!

    51 |
  • 52 |
    Heather

    Thanks for this post!

    53 |
  • 54 |
    Kathy

    Thanks for this post!

    55 |
  • 56 |
    George

    Thanks for this post!

    57 |
  • 58 |
59 |
"""), 60 | ] 61 | 62 | 63 | def make_test_function(example): 64 | 65 | template, context, expected = example 66 | 67 | def test(): 68 | actual = pystache.render(template, context) 69 | if actual != expected: 70 | raise Exception("Benchmark mismatch: \n%s\n*** != ***\n%s" % (expected, actual)) 71 | 72 | return test 73 | 74 | 75 | def main(sys_argv): 76 | args = sys_argv[1:] 77 | count = int(args[0]) 78 | 79 | print "Benchmarking: %sx" % count 80 | print 81 | 82 | for example in examples: 83 | 84 | test = make_test_function(example) 85 | 86 | t = Timer(test,) 87 | print min(t.repeat(repeat=3, number=count)) 88 | 89 | print "Done" 90 | 91 | 92 | if __name__ == '__main__': 93 | main(sys.argv) 94 | 95 | -------------------------------------------------------------------------------- /third_party/pystache/tests/data/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: add a docstring. 3 | 4 | """ 5 | -------------------------------------------------------------------------------- /third_party/pystache/tests/data/ascii.mustache: -------------------------------------------------------------------------------- 1 | ascii: abc -------------------------------------------------------------------------------- /third_party/pystache/tests/data/duplicate.mustache: -------------------------------------------------------------------------------- 1 | This file is used to test locate_path()'s search order. -------------------------------------------------------------------------------- /third_party/pystache/tests/data/locator/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: add a docstring. 3 | 4 | """ 5 | -------------------------------------------------------------------------------- /third_party/pystache/tests/data/locator/duplicate.mustache: -------------------------------------------------------------------------------- 1 | This file is used to test locate_path()'s search order. -------------------------------------------------------------------------------- /third_party/pystache/tests/data/non_ascii.mustache: -------------------------------------------------------------------------------- 1 | non-ascii: é -------------------------------------------------------------------------------- /third_party/pystache/tests/data/sample_view.mustache: -------------------------------------------------------------------------------- 1 | ascii: abc -------------------------------------------------------------------------------- /third_party/pystache/tests/data/say_hello.mustache: -------------------------------------------------------------------------------- 1 | Hello, {{to}} -------------------------------------------------------------------------------- /third_party/pystache/tests/data/views.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | TODO: add a docstring. 5 | 6 | """ 7 | 8 | from pystache import TemplateSpec 9 | 10 | class SayHello(object): 11 | 12 | def to(self): 13 | return "World" 14 | 15 | 16 | class SampleView(TemplateSpec): 17 | pass 18 | 19 | 20 | class NonAscii(TemplateSpec): 21 | pass 22 | -------------------------------------------------------------------------------- /third_party/pystache/tests/doctesting.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Exposes a get_doctests() function for the project's test harness. 5 | 6 | """ 7 | 8 | import doctest 9 | import os 10 | import pkgutil 11 | import sys 12 | import traceback 13 | 14 | if sys.version_info >= (3,): 15 | # Then pull in modules needed for 2to3 conversion. The modules 16 | # below are not necessarily available in older versions of Python. 17 | from lib2to3.main import main as lib2to3main # new in Python 2.6? 18 | from shutil import copyfile 19 | 20 | from pystache.tests.common import TEXT_DOCTEST_PATHS 21 | from pystache.tests.common import get_module_names 22 | 23 | 24 | # This module follows the guidance documented here: 25 | # 26 | # http://docs.python.org/library/doctest.html#unittest-api 27 | # 28 | 29 | def get_doctests(text_file_dir): 30 | """ 31 | Return a list of TestSuite instances for all doctests in the project. 32 | 33 | Arguments: 34 | 35 | text_file_dir: the directory in which to search for all text files 36 | (i.e. non-module files) containing doctests. 37 | 38 | """ 39 | # Since module_relative is False in our calls to DocFileSuite below, 40 | # paths should be OS-specific. See the following for more info-- 41 | # 42 | # http://docs.python.org/library/doctest.html#doctest.DocFileSuite 43 | # 44 | paths = [os.path.normpath(os.path.join(text_file_dir, path)) for path in TEXT_DOCTEST_PATHS] 45 | 46 | if sys.version_info >= (3,): 47 | paths = _convert_paths(paths) 48 | 49 | suites = [] 50 | 51 | for path in paths: 52 | suite = doctest.DocFileSuite(path, module_relative=False) 53 | suites.append(suite) 54 | 55 | modules = get_module_names() 56 | for module in modules: 57 | suite = doctest.DocTestSuite(module) 58 | suites.append(suite) 59 | 60 | return suites 61 | 62 | 63 | def _convert_2to3(path): 64 | """ 65 | Convert the given file, and return the path to the converted files. 66 | 67 | """ 68 | base, ext = os.path.splitext(path) 69 | # For example, "README.temp2to3.rst". 70 | new_path = "%s.temp2to3%s" % (base, ext) 71 | 72 | copyfile(path, new_path) 73 | 74 | args = ['--doctests_only', '--no-diffs', '--write', '--nobackups', new_path] 75 | lib2to3main("lib2to3.fixes", args=args) 76 | 77 | return new_path 78 | 79 | 80 | def _convert_paths(paths): 81 | """ 82 | Convert the given files, and return the paths to the converted files. 83 | 84 | """ 85 | new_paths = [] 86 | for path in paths: 87 | new_path = _convert_2to3(path) 88 | new_paths.append(new_path) 89 | 90 | return new_paths 91 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: add a docstring. 3 | 4 | """ 5 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/comments.mustache: -------------------------------------------------------------------------------- 1 |

{{title}}{{! just something interesting... #or not... }}

-------------------------------------------------------------------------------- /third_party/pystache/tests/examples/comments.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class Comments(object): 8 | 9 | def title(self): 10 | return "A Comedy of Errors" 11 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/complex.mustache: -------------------------------------------------------------------------------- 1 |

{{ header }}

2 | {{#list}} 3 |
    4 | {{#item}}{{# current }}
  • {{name}}
  • 5 | {{/ current }}{{#link}}
  • {{name}}
  • 6 | {{/link}}{{/item}}
{{/list}}{{#empty}}

The list is empty.

{{/empty}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/complex.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class Complex(object): 8 | 9 | def header(self): 10 | return "Colors" 11 | 12 | def item(self): 13 | items = [] 14 | items.append({ 'name': 'red', 'current': True, 'url': '#Red' }) 15 | items.append({ 'name': 'green', 'link': True, 'url': '#Green' }) 16 | items.append({ 'name': 'blue', 'link': True, 'url': '#Blue' }) 17 | return items 18 | 19 | def list(self): 20 | return not self.empty() 21 | 22 | def empty(self): 23 | return len(self.item()) == 0 24 | 25 | def empty_list(self): 26 | return []; 27 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/delimiters.mustache: -------------------------------------------------------------------------------- 1 | {{=<% %>=}} 2 | * <% first %> 3 | <%=| |=%> 4 | * | second | 5 | |={{ }}=| 6 | * {{ third }} 7 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/delimiters.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class Delimiters(object): 8 | 9 | def first(self): 10 | return "It worked the first time." 11 | 12 | def second(self): 13 | return "And it worked the second time." 14 | 15 | def third(self): 16 | return "Then, surprisingly, it worked the third time." 17 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/double_section.mustache: -------------------------------------------------------------------------------- 1 | {{#t}}* first{{/t}} 2 | * {{two}} 3 | {{#t}}* third{{/t}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/double_section.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class DoubleSection(object): 8 | 9 | def t(self): 10 | return True 11 | 12 | def two(self): 13 | return "second" 14 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/escaped.mustache: -------------------------------------------------------------------------------- 1 |

{{title}}

-------------------------------------------------------------------------------- /third_party/pystache/tests/examples/escaped.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class Escaped(object): 8 | 9 | def title(self): 10 | return "Bear > Shark" 11 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/extensionless: -------------------------------------------------------------------------------- 1 | No file extension: {{foo}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/inner_partial.mustache: -------------------------------------------------------------------------------- 1 | Again, {{title}}! -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/inner_partial.txt: -------------------------------------------------------------------------------- 1 | ## Again, {{title}}! ## -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/inverted.mustache: -------------------------------------------------------------------------------- 1 | {{^f}}one{{/f}}, {{ two }}, {{^f}}three{{/f}}{{^t}}, four!{{/t}}{{^empty_list}}, empty list{{/empty_list}}{{^populated_list}}, shouldn't see me{{/populated_list}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/inverted.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache import TemplateSpec 8 | 9 | class Inverted(object): 10 | 11 | def t(self): 12 | return True 13 | 14 | def f(self): 15 | return False 16 | 17 | def two(self): 18 | return 'two' 19 | 20 | def empty_list(self): 21 | return [] 22 | 23 | def populated_list(self): 24 | return ['some_value'] 25 | 26 | class InvertedLists(Inverted, TemplateSpec): 27 | template_name = 'inverted' 28 | 29 | def t(self): 30 | return [0, 1, 2] 31 | 32 | def f(self): 33 | return [] 34 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/lambdas.mustache: -------------------------------------------------------------------------------- 1 | {{#replace_foo_with_bar}}foo != bar. oh, it does!{{/replace_foo_with_bar}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/lambdas.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache import TemplateSpec 8 | 9 | def rot(s, n=13): 10 | r = "" 11 | for c in s: 12 | cc = c 13 | if cc.isalpha(): 14 | cc = cc.lower() 15 | o = ord(cc) 16 | ro = (o+n) % 122 17 | if ro == 0: ro = 122 18 | if ro < 97: ro += 96 19 | cc = chr(ro) 20 | r = ''.join((r,cc)) 21 | return r 22 | 23 | def replace(subject, this='foo', with_this='bar'): 24 | return subject.replace(this, with_this) 25 | 26 | 27 | # This class subclasses TemplateSpec because at least one unit test 28 | # sets the template attribute. 29 | class Lambdas(TemplateSpec): 30 | 31 | def replace_foo_with_bar(self, text=None): 32 | return replace 33 | 34 | def rot13(self, text=None): 35 | return rot 36 | 37 | def sort(self, text=None): 38 | return lambda text: ''.join(sorted(text)) 39 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/looping_partial.mustache: -------------------------------------------------------------------------------- 1 | Looping partial {{item}}! -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/nested_context.mustache: -------------------------------------------------------------------------------- 1 | {{#foo}}{{thing1}} and {{thing2}} and {{outer_thing}}{{/foo}}{{^foo}}Not foo!{{/foo}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/nested_context.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache import TemplateSpec 8 | 9 | class NestedContext(TemplateSpec): 10 | 11 | def __init__(self, renderer): 12 | self.renderer = renderer 13 | 14 | def _context_get(self, key): 15 | return self.renderer.context.get(key) 16 | 17 | def outer_thing(self): 18 | return "two" 19 | 20 | def foo(self): 21 | return {'thing1': 'one', 'thing2': 'foo'} 22 | 23 | def derp(self): 24 | return [{'inner': 'car'}] 25 | 26 | def herp(self): 27 | return [{'outer': 'car'}] 28 | 29 | def nested_context_in_view(self): 30 | if self._context_get('outer') == self._context_get('inner'): 31 | return 'it works!' 32 | return '' 33 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/partial_in_partial.mustache: -------------------------------------------------------------------------------- 1 | {{>simple}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/partial_with_lambda.mustache: -------------------------------------------------------------------------------- 1 | {{#rot13}}abcdefghijklm{{/rot13}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/partial_with_partial_and_lambda.mustache: -------------------------------------------------------------------------------- 1 | {{>partial_with_lambda}}{{#rot13}}abcdefghijklm{{/rot13}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/partials_with_lambdas.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache.tests.examples.lambdas import rot 8 | 9 | class PartialsWithLambdas(object): 10 | 11 | def rot(self): 12 | return rot 13 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/readme.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class SayHello(object): 8 | def to(self): 9 | return "Pizza" 10 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/say_hello.mustache: -------------------------------------------------------------------------------- 1 | Hello, {{to}}! -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/simple.mustache: -------------------------------------------------------------------------------- 1 | Hi {{thing}}!{{blank}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/simple.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache import TemplateSpec 8 | 9 | class Simple(TemplateSpec): 10 | 11 | def thing(self): 12 | return "pizza" 13 | 14 | def blank(self): 15 | return '' 16 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/tagless.mustache: -------------------------------------------------------------------------------- 1 | No tags... -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/template_partial.mustache: -------------------------------------------------------------------------------- 1 |

{{title}}

2 | {{>inner_partial}} -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/template_partial.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache import TemplateSpec 8 | 9 | class TemplatePartial(TemplateSpec): 10 | 11 | def __init__(self, renderer): 12 | self.renderer = renderer 13 | 14 | def _context_get(self, key): 15 | return self.renderer.context.get(key) 16 | 17 | def title(self): 18 | return "Welcome" 19 | 20 | def title_bars(self): 21 | return '-' * len(self.title()) 22 | 23 | def looping(self): 24 | return [{'item': 'one'}, {'item': 'two'}, {'item': 'three'}] 25 | 26 | def thing(self): 27 | return self._context_get('prop') 28 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/template_partial.txt: -------------------------------------------------------------------------------- 1 | {{title}} 2 | {{title_bars}} 3 | 4 | {{>inner_partial}} 5 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/unescaped.mustache: -------------------------------------------------------------------------------- 1 |

{{{title}}}

-------------------------------------------------------------------------------- /third_party/pystache/tests/examples/unescaped.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | class Unescaped(object): 8 | 9 | def title(self): 10 | return "Bear > Shark" 11 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/unicode_input.mustache: -------------------------------------------------------------------------------- 1 | abcdé -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/unicode_input.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | TODO: add a docstring. 4 | 5 | """ 6 | 7 | from pystache import TemplateSpec 8 | 9 | class UnicodeInput(TemplateSpec): 10 | 11 | template_encoding = 'utf8' 12 | 13 | def age(self): 14 | return 156 15 | -------------------------------------------------------------------------------- /third_party/pystache/tests/examples/unicode_output.mustache: -------------------------------------------------------------------------------- 1 |

Name: {{name}}

-------------------------------------------------------------------------------- /third_party/pystache/tests/examples/unicode_output.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | """ 4 | TODO: add a docstring. 5 | 6 | """ 7 | 8 | class UnicodeOutput(object): 9 | 10 | def name(self): 11 | return u'Henri Poincaré' 12 | -------------------------------------------------------------------------------- /third_party/pystache/tests/test___init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Tests of __init__.py. 5 | 6 | """ 7 | 8 | # Calling "import *" is allowed only at the module level. 9 | GLOBALS_INITIAL = globals().keys() 10 | from pystache import * 11 | GLOBALS_PYSTACHE_IMPORTED = globals().keys() 12 | 13 | import unittest 14 | 15 | import pystache 16 | 17 | 18 | class InitTests(unittest.TestCase): 19 | 20 | def test___all__(self): 21 | """ 22 | Test that "from pystache import *" works as expected. 23 | 24 | """ 25 | actual = set(GLOBALS_PYSTACHE_IMPORTED) - set(GLOBALS_INITIAL) 26 | expected = set(['render', 'Renderer', 'TemplateSpec', 'GLOBALS_INITIAL']) 27 | 28 | self.assertEqual(actual, expected) 29 | 30 | def test_version_defined(self): 31 | """ 32 | Test that pystache.__version__ is set. 33 | 34 | """ 35 | actual_version = pystache.__version__ 36 | self.assertTrue(actual_version) 37 | -------------------------------------------------------------------------------- /third_party/pystache/tests/test_commands.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Unit tests of commands.py. 5 | 6 | """ 7 | 8 | import sys 9 | import unittest 10 | 11 | from pystache.commands.render import main 12 | 13 | 14 | ORIGINAL_STDOUT = sys.stdout 15 | 16 | 17 | class MockStdout(object): 18 | 19 | def __init__(self): 20 | self.output = "" 21 | 22 | def write(self, str): 23 | self.output += str 24 | 25 | 26 | class CommandsTestCase(unittest.TestCase): 27 | 28 | def setUp(self): 29 | sys.stdout = MockStdout() 30 | 31 | def callScript(self, template, context): 32 | argv = ['pystache', template, context] 33 | main(argv) 34 | return sys.stdout.output 35 | 36 | def testMainSimple(self): 37 | """ 38 | Test a simple command-line case. 39 | 40 | """ 41 | actual = self.callScript("Hi {{thing}}", '{"thing": "world"}') 42 | self.assertEqual(actual, u"Hi world\n") 43 | 44 | def tearDown(self): 45 | sys.stdout = ORIGINAL_STDOUT 46 | -------------------------------------------------------------------------------- /third_party/pystache/tests/test_parser.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Unit tests of parser.py. 5 | 6 | """ 7 | 8 | import unittest 9 | 10 | from pystache.parser import _compile_template_re as make_re 11 | 12 | 13 | class RegularExpressionTestCase(unittest.TestCase): 14 | 15 | """Tests the regular expression returned by _compile_template_re().""" 16 | 17 | def test_re(self): 18 | """ 19 | Test getting a key from a dictionary. 20 | 21 | """ 22 | re = make_re() 23 | match = re.search("b {{test}}") 24 | 25 | self.assertEqual(match.start(), 1) 26 | 27 | -------------------------------------------------------------------------------- /third_party/repoze/LICENSE.txt: -------------------------------------------------------------------------------- 1 | License 2 | 3 | A copyright notice accompanies this license document that identifies 4 | the copyright holders. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | 1. Redistributions in source code must retain the accompanying 11 | copyright notice, this list of conditions, and the following 12 | disclaimer. 13 | 14 | 2. Redistributions in binary form must reproduce the accompanying 15 | copyright notice, this list of conditions, and the following 16 | disclaimer in the documentation and/or other materials provided 17 | with the distribution. 18 | 19 | 3. Names of the copyright holders must not be used to endorse or 20 | promote products derived from this software without prior 21 | written permission from the copyright holders. 22 | 23 | 4. If any files are modified, you must cause the modified files to 24 | carry prominent notices stating that you changed the files and 25 | the date of any change. 26 | 27 | Disclaimer 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND 30 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 31 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 32 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 35 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 37 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 38 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 39 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 | SUCH DAMAGE. 41 | 42 | -------------------------------------------------------------------------------- /third_party/repoze/__init__.py: -------------------------------------------------------------------------------- 1 | try: 2 | __import__('pkg_resources').declare_namespace(__name__) 3 | except: 4 | pass 5 | -------------------------------------------------------------------------------- /third_party/routes/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005-2008 Ben Bangert 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. The name of the author or contributors may not be used to endorse or 14 | promote products derived from this software without specific prior 15 | written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /third_party/routes/base.py: -------------------------------------------------------------------------------- 1 | """Route and Mapper core classes""" 2 | from routes import request_config 3 | from routes.mapper import Mapper 4 | from routes.route import Route 5 | -------------------------------------------------------------------------------- /third_party/yaml/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006 Kirill Simonov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /third_party/yaml/loader.py: -------------------------------------------------------------------------------- 1 | 2 | __all__ = ['BaseLoader', 'SafeLoader', 'Loader'] 3 | 4 | from reader import * 5 | from scanner import * 6 | from parser import * 7 | from composer import * 8 | from constructor import * 9 | from resolver import * 10 | 11 | class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): 12 | 13 | def __init__(self, stream): 14 | Reader.__init__(self, stream) 15 | Scanner.__init__(self) 16 | Parser.__init__(self) 17 | Composer.__init__(self) 18 | BaseConstructor.__init__(self) 19 | BaseResolver.__init__(self) 20 | 21 | class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): 22 | 23 | def __init__(self, stream): 24 | Reader.__init__(self, stream) 25 | Scanner.__init__(self) 26 | Parser.__init__(self) 27 | Composer.__init__(self) 28 | SafeConstructor.__init__(self) 29 | Resolver.__init__(self) 30 | 31 | class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): 32 | 33 | def __init__(self, stream): 34 | Reader.__init__(self, stream) 35 | Scanner.__init__(self) 36 | Parser.__init__(self) 37 | Composer.__init__(self) 38 | Constructor.__init__(self) 39 | Resolver.__init__(self) 40 | 41 | -------------------------------------------------------------------------------- /third_party/yaml/nodes.py: -------------------------------------------------------------------------------- 1 | 2 | class Node(object): 3 | def __init__(self, tag, value, start_mark, end_mark): 4 | self.tag = tag 5 | self.value = value 6 | self.start_mark = start_mark 7 | self.end_mark = end_mark 8 | def __repr__(self): 9 | value = self.value 10 | #if isinstance(value, list): 11 | # if len(value) == 0: 12 | # value = '' 13 | # elif len(value) == 1: 14 | # value = '<1 item>' 15 | # else: 16 | # value = '<%d items>' % len(value) 17 | #else: 18 | # if len(value) > 75: 19 | # value = repr(value[:70]+u' ... ') 20 | # else: 21 | # value = repr(value) 22 | value = repr(value) 23 | return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value) 24 | 25 | class ScalarNode(Node): 26 | id = 'scalar' 27 | def __init__(self, tag, value, 28 | start_mark=None, end_mark=None, style=None): 29 | self.tag = tag 30 | self.value = value 31 | self.start_mark = start_mark 32 | self.end_mark = end_mark 33 | self.style = style 34 | 35 | class CollectionNode(Node): 36 | def __init__(self, tag, value, 37 | start_mark=None, end_mark=None, flow_style=None): 38 | self.tag = tag 39 | self.value = value 40 | self.start_mark = start_mark 41 | self.end_mark = end_mark 42 | self.flow_style = flow_style 43 | 44 | class SequenceNode(CollectionNode): 45 | id = 'sequence' 46 | 47 | class MappingNode(CollectionNode): 48 | id = 'mapping' 49 | 50 | --------------------------------------------------------------------------------