Преглед на файлове

HUE-7860 [core] Update Gunicorn from 19.7.1 to 19.9.0

Ying Chen преди 7 години
родител
ревизия
8a5a620011
променени са 100 файла, в които са добавени 7782 реда и са изтрити 189 реда
  1. 0 17
      desktop/core/ext-py/gunicorn-19.7.1/gunicorn/workers/gaiohttp.py
  2. 0 2
      desktop/core/ext-py/gunicorn-19.7.1/requirements_test.txt
  3. 11 10
      desktop/core/ext-py/gunicorn-19.9.0/.gitignore
  4. 1 1
      desktop/core/ext-py/gunicorn-19.9.0/LICENSE
  5. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/MANIFEST.in
  6. 1 1
      desktop/core/ext-py/gunicorn-19.9.0/NOTICE
  7. 20 8
      desktop/core/ext-py/gunicorn-19.9.0/PKG-INFO
  8. 13 6
      desktop/core/ext-py/gunicorn-19.9.0/README.rst
  9. 147 144
      desktop/core/ext-py/gunicorn-19.9.0/THANKS
  10. 158 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/Makefile
  11. 19 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/README.rst
  12. 98 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/gunicorn_ext.py
  13. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/logo/gunicorn.png
  14. 114 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/logo/gunicorn.svg
  15. 190 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/make.bat
  16. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/.nojekyll
  17. 1 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/CNAME
  18. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/community.html
  19. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/configuration.html
  20. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/configure.html
  21. 402 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/css/style.css
  22. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/deploy.html
  23. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/deployment.html
  24. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/design.html
  25. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/faq.html
  26. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/about.jpg
  27. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/arrow.png
  28. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/banner-bg.jpg
  29. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/community.jpg
  30. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/documents.jpg
  31. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/downloads.jpg
  32. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/favicon.png
  33. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/footer-arrow.png
  34. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/footer-logo.jpg
  35. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/greenbutton.jpg
  36. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/gunicorn.png
  37. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/large_gunicorn.png
  38. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/logo-bottom.png
  39. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/logo.jpg
  40. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/logo.png
  41. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/redbutton.jpg
  42. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/separator.jpg
  43. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/title.png
  44. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/user1.jpg
  45. 185 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/index.html
  46. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/install.html
  47. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/installation.html
  48. 46 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/js/main.js
  49. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/news.html
  50. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/run.html
  51. 112 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/sitemap.xml
  52. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/tuning.html
  53. 13 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/site/usage.html
  54. 19 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/sitemap_config.xml
  55. 2205 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/sitemap_gen.py
  56. 211 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2010-news.rst
  57. 73 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2011-news.rst
  58. 128 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2012-news.rst
  59. 90 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2013-news.rst
  60. 228 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2014-news.rst
  61. 219 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2015-news.rst
  62. 91 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2016-news.rst
  63. 46 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/2017-news.rst
  64. BIN
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/_static/gunicorn.png
  65. 39 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/community.rst
  66. 73 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/conf.py
  67. 98 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/configure.rst
  68. 16 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/custom.rst
  69. 336 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/deploy.rst
  70. 162 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/design.rst
  71. 199 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/faq.rst
  72. 46 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/index.rst
  73. 144 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/install.rst
  74. 36 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/instrumentation.rst
  75. 80 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/news.rst
  76. 123 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/run.rst
  77. 1308 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/settings.rst
  78. 119 0
      desktop/core/ext-py/gunicorn-19.9.0/docs/source/signals.rst
  79. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/alt_spec.py
  80. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/bad.py
  81. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/boot_fail.py
  82. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/echo.py
  83. 6 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/example_config.py
  84. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/cherryapp.py
  85. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/README
  86. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/manage.py
  87. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/__init__.py
  88. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/__init__.py
  89. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/__init__.py
  90. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/middleware.py
  91. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/models.py
  92. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/templates/base.html
  93. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/templates/home.html
  94. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/tests.py
  95. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/urls.py
  96. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/views.py
  97. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/settings.py
  98. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/urls.py
  99. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/wsgi.py
  100. 0 0
      desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/flask_sendfile.py

+ 0 - 17
desktop/core/ext-py/gunicorn-19.7.1/gunicorn/workers/gaiohttp.py

@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -
-#
-# This file is part of gunicorn released under the MIT license.
-# See the NOTICE for more information.
-
-import sys
-
-if sys.version_info >= (3, 3):
-    try:
-        import aiohttp  # NOQA
-    except ImportError:
-        raise RuntimeError("You need aiohttp installed to use this worker.")
-    else:
-        from gunicorn.workers._gaiohttp import AiohttpWorker
-        __all__ = ['AiohttpWorker']
-else:
-    raise RuntimeError("You need Python >= 3.3 to use the asyncio worker")

+ 0 - 2
desktop/core/ext-py/gunicorn-19.7.1/requirements_test.txt

@@ -1,2 +0,0 @@
-pytest==3.0.5
-pytest-cov==2.4.0

+ 11 - 10
desktop/core/ext-py/gunicorn-19.7.1/.gitignore → desktop/core/ext-py/gunicorn-19.9.0/.gitignore

@@ -1,16 +1,17 @@
-*.pyc
-__pycache__
-MANIFEST
-build
-dist
-setuptools-*
-*.so
 *.egg
 *.egg-info
-nohup.out
+*.pyc
+*.so
 .coverage
+.pytest_cache
+.tox
+__pycache__
+build
 coverage.xml
+dist
+examples/frameworks/django/testing/testdb.sql
 examples/frameworks/pylonstest/PasteScript*
 examples/frameworks/pylonstest/pylonstest.egg-info/
-examples/frameworks/django/testing/testdb.sql
-.tox
+MANIFEST
+nohup.out
+setuptools-*

+ 1 - 1
desktop/core/ext-py/gunicorn-19.7.1/LICENSE → desktop/core/ext-py/gunicorn-19.9.0/LICENSE

@@ -1,4 +1,4 @@
-2009-2017 (c) Benoît Chesneau <benoitc@e-engura.org>
+2009-2018 (c) Benoît Chesneau <benoitc@e-engura.org>
 2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>
 
 Permission is hereby granted, free of charge, to any person

+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/MANIFEST.in → desktop/core/ext-py/gunicorn-19.9.0/MANIFEST.in


+ 1 - 1
desktop/core/ext-py/gunicorn-19.7.1/NOTICE → desktop/core/ext-py/gunicorn-19.9.0/NOTICE

@@ -1,6 +1,6 @@
 Gunicorn
 
-2009-2017 (c) Benoît Chesneau <benoitc@e-engura.org>
+2009-2018 (c) Benoît Chesneau <benoitc@e-engura.org>
 2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>
 
 Gunicorn is released under the MIT license. See the LICENSE

+ 20 - 8
desktop/core/ext-py/gunicorn-19.7.1/PKG-INFO → desktop/core/ext-py/gunicorn-19.9.0/PKG-INFO

@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: gunicorn
-Version: 19.7.1
+Version: 19.9.0
 Summary: WSGI HTTP Server for UNIX
 Home-page: http://gunicorn.org
 Author: Benoit Chesneau
@@ -9,8 +9,15 @@ License: MIT
 Description: Gunicorn
         --------
         
-        .. image::
-            https://secure.travis-ci.org/benoitc/gunicorn.png?branch=master
+        .. image:: https://img.shields.io/pypi/v/gunicorn.svg?style=flat
+            :alt: PyPI version
+            :target: https://pypi.python.org/pypi/gunicorn
+        
+        .. image:: https://img.shields.io/pypi/pyversions/gunicorn.svg
+            :alt: Supported Python versions
+            :target: https://pypi.python.org/pypi/gunicorn
+        
+        .. image:: https://travis-ci.org/benoitc/gunicorn.svg?branch=master
             :alt: Build Status
             :target: https://travis-ci.org/benoitc/gunicorn
         
@@ -59,10 +66,10 @@ Description: Gunicorn
         Gunicorn is released under the MIT License. See the LICENSE_ file for more
         details.
         
-        .. _Unicorn: http://unicorn.bogomips.org/
-        .. _`#gunicorn`: http://webchat.freenode.net/?channels=gunicorn
-        .. _Freenode: http://freenode.net
-        .. _LICENSE: http://github.com/benoitc/gunicorn/blob/master/LICENSE
+        .. _Unicorn: https://bogomips.org/unicorn/
+        .. _`#gunicorn`: https://webchat.freenode.net/?channels=gunicorn
+        .. _Freenode: https://freenode.net/
+        .. _LICENSE: https://github.com/benoitc/gunicorn/blob/master/LICENSE
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
@@ -88,3 +95,8 @@ Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Server
 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*
+Provides-Extra: tornado
+Provides-Extra: gevent
+Provides-Extra: eventlet
+Provides-Extra: gthread

+ 13 - 6
desktop/core/ext-py/gunicorn-19.7.1/README.rst → desktop/core/ext-py/gunicorn-19.9.0/README.rst

@@ -1,8 +1,15 @@
 Gunicorn
 --------
 
-.. image::
-    https://secure.travis-ci.org/benoitc/gunicorn.png?branch=master
+.. image:: https://img.shields.io/pypi/v/gunicorn.svg?style=flat
+    :alt: PyPI version
+    :target: https://pypi.python.org/pypi/gunicorn
+
+.. image:: https://img.shields.io/pypi/pyversions/gunicorn.svg
+    :alt: Supported Python versions
+    :target: https://pypi.python.org/pypi/gunicorn
+
+.. image:: https://travis-ci.org/benoitc/gunicorn.svg?branch=master
     :alt: Build Status
     :target: https://travis-ci.org/benoitc/gunicorn
 
@@ -51,7 +58,7 @@ License
 Gunicorn is released under the MIT License. See the LICENSE_ file for more
 details.
 
-.. _Unicorn: http://unicorn.bogomips.org/
-.. _`#gunicorn`: http://webchat.freenode.net/?channels=gunicorn
-.. _Freenode: http://freenode.net
-.. _LICENSE: http://github.com/benoitc/gunicorn/blob/master/LICENSE
+.. _Unicorn: https://bogomips.org/unicorn/
+.. _`#gunicorn`: https://webchat.freenode.net/?channels=gunicorn
+.. _Freenode: https://freenode.net/
+.. _LICENSE: https://github.com/benoitc/gunicorn/blob/master/LICENSE

+ 147 - 144
desktop/core/ext-py/gunicorn-19.7.1/THANKS → desktop/core/ext-py/gunicorn-19.9.0/THANKS

@@ -4,169 +4,172 @@ Gunicorn THANKS
 A number of people have contributed to Gunicorn by reporting problems,
 suggesting improvements or submitting changes. Some of these people are:
 
-Benoit Chesneau <bchesneau@gmail.com>
-Paul J. Davis <paul.joseph.davis@gmail.com>
-Curt Micol <asenchi@asenchi.com>
-Eric Florenzano <floguy@gmail.com>
-Johan Bergström <bugs@bergstroem.nu>
-Jannis Leidel <jannis@leidel.info>
-Jonas Nockert <jonasnockert@gmail.com>
-Paul Davis <davisp@neb.com>
-Paul Smith <paulsmith@pobox.com>
-Randall Leeds <randall@meebo-inc.com>
-Thomas Steinacher <tom@eggdrop.ch>
-Greg Taylor <gtaylor@duointeractive.com>
-Randall Leeds <randall.leeds@gmail.com>
-George Kollias <georgioskollias@gmail.com>
-PA Parent <paparent@paparent.me>
-Bartosz Oler <bartosz@bzimage.us>
+414nch4n <chanfung032@gmail.com>
+Aaron Kavlie <akavlie@gmail.com>
+aartur <asiekielski@soldevelo.com>
+Adnane Belmadiaf <adnane002@gmail.com>
+Adrien CLERC <adrien@antipoul.fr>
+Alasdair Nicol <alasdair@thenicols.net>
+Alex Conrad <alexandre.conrad@gmail.com>
+Alex Gaynor <alex.gaynor@gmail.com>
+Alex Robbins <alexander.j.robbins@gmail.com>
+Alexandre Zani <alexandre.zani@gmail.com>
+Alexis Le-Quoc <alq@datadoghq.com>
 Anand Chitipothu <anandology@gmail.com>
-Travis Cline <travis.cline@gmail.com>
-Travis Swicegood <development@domain51.com>
-Oliver Tonnhofer <olt@bogosoft.com>
+Andreas Stührk <andy-python@hammerhartes.de>
+Andrew Burdo <zeezooz@gmail.com>
+Andrew Svetlov <andrew.svetlov@gmail.com>
+Anil V <avaitla16@gmail.com>
+Antoine Girard <antoine.girard.dev@gmail.com>
+Anton Vlasenko <antares.spica@gmail.com>
+Bartosz Oler <bartosz@bzimage.us>
 Ben Cochran <bcochran@gmail.com>
-Justin Quick <justquick@gmail.com>
-Neil Chintomby <nchintomby@gmail.com>
-Alex Robbins <alexander.j.robbins@gmail.com>
-Graham Dumpleton <graham@newrelic.com>
-Dan Sully <daniel-github@electricrain.com>
-Aaron Kavlie <akavlie@gmail.com>
-Michael Schurter <m@schmichael.com>
-WoLpH <Rick@Fawo.nl>
-Jim Garrison <jim@garrison.cc>
-Keegan Carruthers-Smith <keegan.csmith@gmail.com>
-John Hensley <john@fairviewcomputing.com>
-Brian Rosner <brosner@gmail.com>
-Denis Bilenko <denis.bilenko@gmail.com>
-Phil Schanely <phil@daylife.com>
-Chris Lamb <lamby@debian.org>
-Kristian Øllegaard <kristian.ollegaard@divio.ch>
+Ben Oswald <ben.oswald@root-space.de>
 Benjamin Gilbert <bgilbert@backtick.net>
-Evan Mezeske <evan@meebo-inc.com>
-Sergey Rublev <narma.nsk@gmail.com>
-Kristian Glass <git@doismellburning.co.uk>
-Mazdak Rezvani <mazdak@mac.com>
-Maxim Kamenkov <mkamenkov@gmail.com>
-Chris Forbes <chrisf@ijw.co.nz>
-Konstantin Kapustin <sirkonst@gmail.com>
+Benoit Chesneau <bchesneau@gmail.com>
+Berker Peksag <berker.peksag@gmail.com>
+bninja <andrew@poundpay.com>
+Bob Hagemann <bob+code@twilio.com>
 Bobby Beckmann <bobby@macs-MacBook-Pro.local>
-Wojtek <wojtek@monodev.com>
-Djoume Salvetti <djoume@freshbooks.com>
-shouse-cars <shouse@cars.com>
-CMGS <ilskdw@mspil.edu.cn>
-Christoph Heer <Christoph.Heer@gmail.com>
-414nch4n <chanfung032@gmail.com>
-Caleb Brown <git@calebbrown.id.au>
-Marc Abramowitz <marc@marc-abramowitz.com>
-Leonardo Santagada <santagada@gmail.com>
-aartur <asiekielski@soldevelo.com>
-Xie Shi <xieshi@douban.com>
-Prateek Singh Paudel <pratykschingh@gmail.com>
-zakdances <zakdances@gmail.com>
-mpaolini <markopaolini@gmail.com>
+Brian Rosner <brosner@gmail.com>
 Bruno Bigras <bigras.bruno@gmail.com>
-Eric Shull <eric@elevenbasetwo.com>
-Christos Stavrakakis <cstavr@grnet.gr>
-sib <andrew.sibley@gmail.com>
+Caleb Brown <git@calebbrown.id.au>
 Chris Adams <chris@improbable.org>
-Mike Tigas <mike@tig.as>
-Qiangning Hong <hongqn@douban.com>
-David Vincelli <david@freshbooks.com>
-Adnane Belmadiaf <adnane002@gmail.com>
+Chris Forbes <chrisf@ijw.co.nz>
+Chris Lamb <lamby@debian.org>
+Chris Streeter <chris@chrisstreeter.com>
+Christoph Heer <Christoph.Heer@gmail.com>
+Christos Stavrakakis <cstavr@grnet.gr>
+CMGS <ilskdw@mspil.edu.cn>
+Curt Micol <asenchi@asenchi.com>
 Dan Callaghan <dcallagh@redhat.com>
-Greg McGuire <greg-github@greganem.com>
+Dan Sully <daniel-github@electricrain.com>
+Daniel Quinn <code@danielquinn.org>
+Dariusz Suchojad <dsuch-github@m.zato.io>
+David Vincelli <david@freshbooks.com>
+David Wolever <david@wolever.net>
+Denis Bilenko <denis.bilenko@gmail.com>
+Diego Oliveira <contact@diegoholiveira.com>
+Dima Barsky <github@kappa.ac93.org>
+Djoume Salvetti <djoume@freshbooks.com>
 Dmitry Medvinsky <me@dmedvinsky.name>
-Shane Reustle <me@shanereustle.com>
-Anton Vlasenko <antares.spica@gmail.com>
-Stephane Wirtel <stephane@wirtel.be>
-Mahmoud Hashemi <mahmoudrhashemi@gmail.com>
-Chris Streeter <chris@chrisstreeter.com>
-Matt Behrens <askedrelic@gmail.com>
+Ed Morley <edmorley@users.noreply.github.com>
+Eric Florenzano <floguy@gmail.com>
+Eric Shull <eric@elevenbasetwo.com>
+Eugene Obukhov <irvind25@gmail.com>
+Evan Mezeske <evan@meebo-inc.com>
+Gaurav Kumar <gauravkumar37@gmail.com>
+George Kollias <georgioskollias@gmail.com>
+George Notaras <gnot@g-loaded.eu>
 German Larrain <germanlarrainm@gmail.com>
-Ronan Amicel <ronan.amicel@gmail.com>
-Kevin Luikens <kluikens@gmail.com>
-Kyle Kelley <rgbkrk@gmail.com>
-jean-philippe serafin <serafinjp@gmail.com>
-Krzysztof Urbaniak <urban@fail.pl>
-Alexandre Zani <alexandre.zani@gmail.com>
 Graham Dumpleton <Graham.Dumpleton@gmail.com>
-Kevin Gessner <kevin@kevingessner.com>
-Andreas Stührk <andy-python@hammerhartes.de>
+Graham Dumpleton <graham@newrelic.com>
+Greg McGuire <greg-github@greganem.com>
+Greg Taylor <gtaylor@duointeractive.com>
+Hasan Ramezani <hasan.r67@gmail.com>
+Hebert J <hebert@mail.ru>
+Hobson Lane <shopper@totalgood.com>
+Igor Petrov <igor.s.petrov@gmail.com>
+INADA Naoki <methane@users.noreply.github.com>
+Jakub Paweł Głazik <zytek@nuxi.pl>
+Jan-Philip Gehrcke <jgehrcke@googlemail.com>
+Jannis Leidel <jannis@leidel.info>
+Jason Madden <jason@nextthought.com>
+jean-philippe serafin <serafinjp@gmail.com>
+Jeremy Volkman <jeremy@jvolkman.com>
+Jeryn Mathew <jerynmathew@gmail.com>
 Jet Sun <jet.joins.sun@gmail.com>
-Gaurav Kumar <gauravkumar37@gmail.com>
+Jim Garrison <jim@garrison.cc>
+Johan Bergström <bugs@bergstroem.nu>
+John Hensley <john@fairviewcomputing.com>
+Jonas Haag <jonas@lophus.org>
+Jonas Nockert <jonasnockert@gmail.com>
 Jorge Niedbalski <jorge@nimbic.com>
-Lars Hansson <romabysen@gmail.com>
-Philip Cristiano <philipcristiano@gmail.com>
 Jorge Niedbalski R <niedbalski@gmail.com>
-Moriyoshi Koizumi <mozo@mozo.jp>
-Jeremy Volkman <jeremy@jvolkman.com>
-py <py@douban.com>
-Dima Barsky <github@kappa.ac93.org>
-Alex Gaynor <alex.gaynor@gmail.com>
-Stephen DiCato <Locker537@gmail.com>
-Simon Lundmark <simon.lundmark@gmail.com>
-wong2 <wonderfuly@gmail.com>
-kracekumar <kracethekingmaker@gmail.com>
+Justin Quick <justquick@gmail.com>
 keakon <keakon@gmail.com>
-Steven Cummings <estebistec@gmail.com>
-WooParadog <guohaochuan@gmail.com>
-Mieszko <mieszko.chowaniec@gmail.com>
+Keegan Carruthers-Smith <keegan.csmith@gmail.com>
 Kenneth Reitz <me@kennethreitz.org>
-David Wolever <david@wolever.net>
-Omer Katz <omer.drow@gmail.com>
-Alasdair Nicol <alasdair@thenicols.net>
-Anil V <avaitla16@gmail.com>
-Igor Petrov <igor.s.petrov@gmail.com>
-Neil Williams <neil@reddit.com>
-George Notaras <gnot@g-loaded.eu>
-Raphaël Slinckx <rslinckx@gmail.com>
-Dariusz Suchojad <dsuch-github@m.zato.io>
-Randall Leeds <randall@bleeds.info>
+Kevin Gessner <kevin@kevingessner.com>
+Kevin Littlejohn <kevin@littlejohn.id.au>
+Kevin Luikens <kluikens@gmail.com>
+Kirill Zaborsky <qrilka@gmail.com>
+Konstantin Kapustin <sirkonst@gmail.com>
+kracekumar <kracethekingmaker@gmail.com>
+Kristian Glass <git@doismellburning.co.uk>
+Kristian Øllegaard <kristian.ollegaard@divio.ch>
+Krzysztof Urbaniak <urban@fail.pl>
+Kyle Kelley <rgbkrk@gmail.com>
+Kyle Mulka <repalviglator@yahoo.com>
+Lars Hansson <romabysen@gmail.com>
+Leonardo Santagada <santagada@gmail.com>
+Levi Gross <levi@levigross.com>
 Łukasz Kucharski <lkucharski@leon.pl>
+Mahmoud Hashemi <mahmoudrhashemi@gmail.com>
 Malthe Borch <mborch@gmail.com>
-Adrien CLERC <adrien@antipoul.fr>
-Rik <rvachterberg@gmail.com>
-Levi Gross <levi@levigross.com>
-Trey Long <trey@ktrl.com>
-Jeryn Mathew <jerynmathew@gmail.com>
-Berker Peksag <berker.peksag@gmail.com>
-W. Trevor King <wking@tremily.us>
-Kirill Zaborsky <qrilka@gmail.com>
-Bob Hagemann <bob+code@twilio.com>
-Sébastien Fievet <zyegfryed@gmail.com>
-Stephen Holsapple <sholsapp@gmail.com>
-Hobson Lane <shopper@totalgood.com>
-Alexis Le-Quoc <alq@datadoghq.com>
-Yue Du <ifduyue@gmail.com>
-Nick Pillitteri <nick@tshlabs.org>
-TedWantsMore <TedWantsMore@gmx.com>
-Matt Robenolt <m@robenolt.com>
-Ben Oswald <ben.oswald@root-space.de>
-bninja <andrew@poundpay.com>
-Philipp Saveliev <fsfeel@gmail.com>
+Marc Abramowitz <marc@marc-abramowitz.com>
+Marc Abramowitz <msabramo@gmail.com>
+Mark Adams <mark@markadams.me>
+Matt Behrens <askedrelic@gmail.com>
 Matt Billenstein <mattb@flingo.tv>
+Matt Good <matt@matt-good.net>
+Matt Robenolt <m@robenolt.com>
+Maxim Kamenkov <mkamenkov@gmail.com>
+Mazdak Rezvani <mazdak@mac.com>
+Michael Schurter <m@schmichael.com>
+Mieszko <mieszko.chowaniec@gmail.com>
+Mike Tigas <mike@tig.as>
+Moriyoshi Koizumi <mozo@mozo.jp>
+mpaolini <markopaolini@gmail.com>
+Neil Chintomby <nchintomby@gmail.com>
+Neil Williams <neil@reddit.com>
+Nick Pillitteri <nick@tshlabs.org>
+Nik Nyby <nnyby@columbia.edu>
 Nikolay Kim <fafhrd91@gmail.com>
-Andrew Svetlov <andrew.svetlov@gmail.com>
-Andrew Burdo <zeezooz@gmail.com>
+Oliver Bristow <evilumbrella+github@gmail.com>
+Oliver Tonnhofer <olt@bogosoft.com>
+Omer Katz <omer.drow@gmail.com>
+PA Parent <paparent@paparent.me>
+Paul Davis <davisp@neb.com>
+Paul J. Davis <paul.joseph.davis@gmail.com>
+Paul Smith <paulsmith@pobox.com>
+Phil Schanely <phil@daylife.com>
+Philip Cristiano <philipcristiano@gmail.com>
+Philipp Saveliev <fsfeel@gmail.com>
+Prateek Singh Paudel <pratykschingh@gmail.com>
+py <py@douban.com>
+Qiangning Hong <hongqn@douban.com>
+Randall Leeds <randall.leeds@gmail.com>
+Randall Leeds <randall@bleeds.info>
+Randall Leeds <randall@meebo-inc.com>
+Raphaël Slinckx <rslinckx@gmail.com>
 Rhys Powell <rhys@rhyspowell.com>
+Rik <rvachterberg@gmail.com>
+Ronan Amicel <ronan.amicel@gmail.com>
+Ryan Peck <ryan@rypeck.com>
+Saeed Gharedaghi <saeed.ghx68@gmail.com>
+Sergey Rublev <narma.nsk@gmail.com>
+Shane Reustle <me@shanereustle.com>
+shouse-cars <shouse@cars.com>
+sib <andrew.sibley@gmail.com>
+Simon Lundmark <simon.lundmark@gmail.com>
+Stephane Wirtel <stephane@wirtel.be>
+Stephen DiCato <Locker537@gmail.com>
+Stephen Holsapple <sholsapp@gmail.com>
+Steven Cummings <estebistec@gmail.com>
+Sébastien Fievet <zyegfryed@gmail.com>
+TedWantsMore <TedWantsMore@gmx.com>
 Thomas Grainger <tagrain@gmail.com>
-INADA Naoki <methane@users.noreply.github.com>
-Daniel Quinn <code@danielquinn.org>
-Jakub Paweł Głazik <zytek@nuxi.pl>
-Matt Good <matt@matt-good.net>
-Kyle Mulka <repalviglator@yahoo.com>
-Marc Abramowitz <msabramo@gmail.com>
-Hebert J <hebert@mail.ru>
-Kevin Littlejohn <kevin@littlejohn.id.au>
+Thomas Steinacher <tom@eggdrop.ch>
+Travis Cline <travis.cline@gmail.com>
+Travis Swicegood <development@domain51.com>
+Trey Long <trey@ktrl.com>
+W. Trevor King <wking@tremily.us>
+Wojtek <wojtek@monodev.com>
 Wolfgang Schnerring <wosc@wosc.de>
-Jason Madden <jason@nextthought.com>
-Eugene Obukhov <irvind25@gmail.com>
-Jan-Philip Gehrcke <jgehrcke@googlemail.com>
-Mark Adams <mark@markadams.me>
-Hasan Ramezani <hasan.r67@gmail.com>
-Jonas Haag <jonas@lophus.org>
-Saeed Gharedaghi <saeed.ghx68@gmail.com>
-Ryan Peck <ryan@rypeck.com>
-Alex Conrad <alexandre.conrad@gmail.com>
-Nik Nyby <nnyby@columbia.edu>
-Ed Morley <edmorley@users.noreply.github.com>
+WoLpH <Rick@Fawo.nl>
+wong2 <wonderfuly@gmail.com>
+WooParadog <guohaochuan@gmail.com>
+Xie Shi <xieshi@douban.com>
+Yue Du <ifduyue@gmail.com>
+zakdances <zakdances@gmail.com>

+ 158 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/Makefile

@@ -0,0 +1,158 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+PYTHON        = python
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html htmlview dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  htmlview   to open the index page built by the html target in your browser"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+htmlview: html
+	$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Gunicorn.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Gunicorn.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/Gunicorn"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Gunicorn"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."

+ 19 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/README.rst

@@ -0,0 +1,19 @@
+Generate Documentation
+======================
+
+Requirements
+------------
+
+To generate documentation you need to install:
+
+ - Python >= 2.5
+ - Sphinx (http://sphinx-doc.org/)
+
+
+Generate html
+-------------
+::
+
+    $ make html
+
+The command generates html document inside ``build/html`` dir.

+ 98 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/gunicorn_ext.py

@@ -0,0 +1,98 @@
+import os
+import inspect
+
+from docutils import nodes, utils
+
+import gunicorn.config as guncfg
+
+HEAD = """\
+.. Please update gunicorn/config.py instead.
+
+.. _settings:
+
+Settings
+========
+
+This is an exhaustive list of settings for Gunicorn. Some settings are only
+able to be set from a configuration file. The setting name is what should be
+used in the configuration file. The command line arguments are listed as well
+for reference on setting at the command line.
+
+.. note::
+
+    Settings can be specified by using environment variable
+    ``GUNICORN_CMD_ARGS``. All available command line arguments can be used.
+    For example, to specify the bind address and number of workers::
+
+        $ GUNICORN_CMD_ARGS="--bind=127.0.0.1 --workers=3" gunicorn app:app
+
+    .. versionadded:: 19.7
+
+"""
+ISSUE_URI = 'https://github.com/benoitc/gunicorn/issues/%s'
+PULL_REQUEST_URI = 'https://github.com/benoitc/gunicorn/pull/%s'
+
+
+def format_settings(app):
+    settings_file = os.path.join(app.srcdir, "settings.rst")
+    ret = []
+    known_settings = sorted(guncfg.KNOWN_SETTINGS, key=lambda s: s.section)
+    for i, s in enumerate(known_settings):
+        if i == 0 or s.section != known_settings[i - 1].section:
+            ret.append("%s\n%s\n\n" % (s.section, "-" * len(s.section)))
+        ret.append(fmt_setting(s))
+
+    with open(settings_file, 'w') as settings:
+        settings.write(HEAD)
+        settings.write(''.join(ret))
+
+
+def fmt_setting(s):
+    if callable(s.default):
+        val = inspect.getsource(s.default)
+        val = "\n".join("    %s" % l for l in val.splitlines())
+        val = " ::\n\n" + val
+    elif s.default == '':
+        val = "``(empty string)``"
+    else:
+        val = "``%s``" % s.default
+
+    if s.cli and s.meta:
+        args = ["%s %s" % (arg, s.meta) for arg in s.cli]
+        cli = ', '.join(args)
+    elif s.cli:
+        cli = ", ".join(s.cli)
+
+    out = []
+    out.append(".. _%s:\n" % s.name.replace("_", "-"))
+    out.append("%s" % s.name)
+    out.append("~" * len(s.name))
+    out.append("")
+    if s.cli:
+        out.append("* ``%s``" % cli)
+    out.append("* %s" % val)
+    out.append("")
+    out.append(s.desc)
+    out.append("")
+    out.append("")
+    return "\n".join(out)
+
+
+def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
+    issue = utils.unescape(text)
+    text = 'issue ' + issue
+    refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue)
+    return [refnode], []
+
+
+def pull_request_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
+    issue = utils.unescape(text)
+    text = 'pull request ' + issue
+    refnode = nodes.reference(text, text, refuri=PULL_REQUEST_URI % issue)
+    return [refnode], []
+
+
+def setup(app):
+    app.connect('builder-inited', format_settings)
+    app.add_role('issue', issue_role)
+    app.add_role('pr', pull_request_role)

BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/logo/gunicorn.png


Файловите разлики са ограничени, защото са твърде много
+ 114 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/logo/gunicorn.svg


+ 190 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/make.bat

@@ -0,0 +1,190 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+set I18NSPHINXOPTS=%SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  texinfo    to make Texinfo files
+	echo.  gettext    to make PO message catalogs
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Gunicorn.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Gunicorn.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "texinfo" (
+	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+	goto end
+)
+
+if "%1" == "gettext" (
+	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end

+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/__init__.py → desktop/core/ext-py/gunicorn-19.9.0/docs/site/.nojekyll


+ 1 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/CNAME

@@ -0,0 +1 @@
+gunicorn.org

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/community.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#community">
+    <title>Green Unicorn - Community</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/index.html#community">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/configuration.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Configuration</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/configure.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Configure</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 402 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/css/style.css

@@ -0,0 +1,402 @@
+html,body {
+    margin: 0;
+    padding: 0;
+}
+
+h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,cite,
+code,del,dfn,em,img,q,s,samp,small,strike,strong,sub,sup,tt,var,
+dd,dl,dt,li,ol,ul,fieldset,form,label,legend,button,table,caption,
+tbody,tfoot,thead,tr,th,td {
+    margin: 0;
+    padding: 0;
+    border: 0;
+    font: inherit;
+    vertical-align: baseline;
+}
+
+ol,ul {
+    list-style: none;
+}
+
+html {
+    overflow-y: scroll;
+    font-size: 100%;
+    -webkit-text-size-adjust: 100%;
+    -ms-text-size-adjust: 100%;
+}
+
+a:hover, a:active, a:focus {
+    outline: 0;
+}
+
+img {
+    border: 0;
+    -ms-interpolation-mode: bicubic;
+}
+
+body {
+    background: #F8F8F3;
+    margin: 0;
+    font: 14px/1.4 "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, "Lucida Grande", sans-serif;
+    color: #67686B;
+    height: auto;
+}
+
+a,
+a:hover {
+    text-decoration: none;
+}
+
+.clearall {
+    clear: both;
+    display: block;
+    overflow: hidden;
+    visibility: hidden;
+    width: 0;
+    height: 0;
+}
+
+.logo-wrapper {
+    border-bottom: 1px solid #2A8729;
+}
+
+.latest {
+    width: 150px;
+    top: 0;
+    display: block;
+    float: right;
+    font-weight: bold;
+}
+
+
+.logo-div {
+    width: 1000px;
+    margin: 0 auto;
+    padding: 5px;
+    height: 72px;
+}
+
+.logo {
+    width: 250px;
+    margin: 0 auto;
+    height: 119px;
+    background: url(../images/logo-bottom.png) no-repeat bottom center;
+    position: relative;
+    z-index: 99999;
+}
+
+.banner-wrapper {
+    background: url(../images/banner-bg.jpg) repeat;
+    display: block;
+    width: 100%;
+    min-height: 365px;
+    margin-top: 1px;
+    margin-bottom: 1px;
+}
+
+.banner {
+    width: 1000px;
+    margin: 0 auto;
+    padding: 15px;
+}
+
+.title {
+    width: 250px;
+    margin: 0 auto;
+    margin-top: 32px;
+    text-align:center;
+}
+
+.banner h1 {
+    font-size: 20px;
+    color: #FFF;
+    margin: 15px 10px 0;
+    padding: 5px 40px;
+    text-align: center;
+    line-height: 28px;
+}
+
+.greenbutton {
+    background: url(../images/greenbutton.jpg) repeat-x;
+    height: 54px;
+    width: 224px;
+    line-height: 54px;
+    display: inline-block;
+    text-align: center;
+    border-radius: 3px;
+    border: solid 1px #1D692D;
+    color: #fff;
+    font-size: 22px;
+    letter-spacing: 1px;
+    text-shadow: 1px 1px 1px #000;
+}
+
+.greenbutton:hover {
+    background: url(../images/greenbutton.jpg) repeat-x bottom;
+}
+
+.redbutton {
+    background: url(../images/redbutton.jpg) repeat-x;
+    height: 54px;
+    width: 224px;
+    line-height: 54px;
+    display: inline-block;
+    text-align: center;
+    border-radius: 3px;
+    border: solid 1px #7D180A;
+    color: #fff;
+    font-size: 22px;
+    letter-spacing: 1px;
+    text-shadow: 1px 1px 1px #000;
+}
+
+.redbutton:hover {
+    background: url(../images/redbutton.jpg) repeat-x bottom;
+}
+
+.banner-button {
+    width: 460px;
+    margin: 0 auto;
+    margin-top: 30px;
+}
+
+.banner-link {
+    width: 250px;
+    margin: 0 auto;
+    margin-top: 15px;
+    padding: 5px;
+    text-align: center;
+}
+
+.banner-link a {
+    color: #fff;
+    font-weight: 700;
+    letter-spacing: 1px;
+}
+
+.banner-link a:hover {
+    color: #000;
+}
+
+.mid-wrapper {
+    width: 100%;
+    border-top: 1px solid #2A8729;
+    padding-top: 15px;
+}
+
+.tabs {
+    width: 1000px;
+    margin: 0 auto;
+    padding: 3px;
+    margin-top: 5px;
+    margin-bottom: 25px;
+}
+
+.tab-bar li {
+    width: 230px;
+    padding: 3px;
+    text-align: center;
+    float: left;
+    margin-right: 5px;
+    margin-left: 6px;
+}
+
+.tab-bar li a {
+    display: inline-block;
+}
+
+.tab-bar li a:hover > p,
+.tab-bar li a:hover > h2 {
+    color: #1D692D;
+}
+
+.tab-bar li a p,
+.tab-bar li a h2 {
+    color: #404028;
+    margin-top: 8px;
+    line-height: 1.2;
+}
+
+.tab-bar li a h2 {
+    font-weight: 700;
+    text-transform: uppercase;
+}
+
+.withborder {
+    background: url(../images/separator.jpg) no-repeat;
+}
+
+.gabout, .gcommunity, .gdownloads, .gdocuments {
+    height: 80px;
+    width: 230px;
+    padding-top: 118px;
+}
+
+.gabout {
+    background: url(../images/about.jpg) no-repeat 50% 0;
+}
+
+.gcommunity {
+    background: url(../images/community.jpg) no-repeat 50% 0;
+}
+
+.gdocuments {
+    background: url(../images/documents.jpg) no-repeat 50% 0;
+}
+
+.gdownloads {
+    background: url(../images/downloads.jpg) no-repeat 50% 0;
+}
+
+.tabs li.active a,
+.gabout:hover,
+.gcommunity:hover,
+.gdocuments:hover,
+.gdownloads:hover {
+    background-position: 50% -220px;
+}
+
+.tabs div {
+    display:none;
+}
+
+.tabs div.active {
+    display: block;
+}
+
+.tab-box {
+    color: #3F3F27;
+    border: 1px solid #DDDDD5;
+    padding: 25px 35px;
+    position: relative;
+    margin-top: 20px;
+    border-radius: 3px;
+}
+
+.tab-box h1 {
+    font-size: 28px;
+    color: #2A8729;
+}
+
+.tab-box p {
+    margin: 0 0 9px;
+}
+
+.tab-box ul {
+    padding-left: 40px;
+}
+
+.tab-box li {
+    list-style: disc;
+    margin: 0 0 9px;
+}
+
+.tab-box a,
+.latest a {
+    color: #3F3F27;
+    text-decoration: underline;
+}
+
+.tab-box a:hover,
+.latest a:hover {
+    color: #1D692D;
+}
+
+.arrow {
+    background: url(../images/arrow.png) no-repeat;
+    position: absolute;
+    left: 115px;
+    top: -7px;
+    height: 10px;
+    width: 20px;
+}
+
+pre {
+    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+    font-size: 14px;
+    color: #333333;
+    display: block;
+    padding: 8.5px;
+    margin: 0 0 9px;
+    font-size: 14px;
+    line-height: 18px;
+    word-break: break-all;
+    word-wrap: break-word;
+    white-space: pre;
+    white-space: pre-wrap;
+    background-color: #EEFFCC;
+    border-top: 1px solid #A9CC99;
+    border-bottom: 1px solid #A9CC99;
+}
+
+.user-wrapper {
+    background: url(../images/banner-bg.jpg) repeat;
+    height: 110px;
+}
+
+.users {
+    width: 1000px;
+    padding: 20px 5px;
+    margin: 0 auto;
+    color: #fff;
+}
+
+.users h3 {
+    font-size: 12px;
+    margin-left: 5px;
+    padding-top: 15px;
+}
+
+.users h2 {
+    font-size: 26px;
+    margin-left: 5px;
+}
+
+.users .left-details {
+    width: 120px;
+    float: left;
+    height: 66px;
+    background: url(../images/footer-arrow.png) no-repeat top right;
+    padding-right: 15px;
+    text-align: right;
+}
+
+.users .company-logos {
+    float: left;
+    width: 820px;
+    height: 70px;
+    margin-left: 20px;
+}
+
+.users .company-logos a img {
+    float: left;
+    border: solid 1px #004000;
+    margin: 0 6px;
+}
+
+.users .company-logos a:hover img {
+    border: solid 1px #000;
+}
+
+.footer {
+    background-color: #F8F8F3;
+    display: block;
+    height: 70px;
+}
+
+.footer .footer-wp {
+    margin: 0 auto;
+    padding: 15px 5px;
+    width: 930px;
+    background: url(../images/footer-logo.jpg) no-repeat 0 50%;
+    padding-left: 70px;
+}
+
+.footer-wp a {
+    color: #3F3F27;
+    text-decoration: underline;
+}
+
+.footer-wp a:hover {
+    color: #1D692D;
+}

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/deploy.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#deployment">
+    <title>Green Unicorn - Deployment</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/index.html#deployment">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/deployment.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#deployment">
+    <title>Green Unicorn - Deployment</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/index.html#deployment">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/design.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Design</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/faq.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - FAQ</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/about.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/arrow.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/banner-bg.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/community.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/documents.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/downloads.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/favicon.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/footer-arrow.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/footer-logo.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/greenbutton.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/gunicorn.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/large_gunicorn.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/logo-bottom.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/logo.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/logo.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/redbutton.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/separator.jpg


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/title.png


BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/site/images/user1.jpg


+ 185 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/index.html

@@ -0,0 +1,185 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8" />
+  <title>Gunicorn - Python WSGI HTTP Server for UNIX</title>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+  <link rel="stylesheet" type="text/css" href="css/style.css" />
+  <link rel="shortcut icon" href="images/favicon.png" type="image/x-icon">
+  <link rel="alternate"
+  href="https://github.com/benoitc/gunicorn/commits/master.atom"
+  type="application/atom+xml" title="Gunicorn commits">
+
+</head>
+<body>
+  <div class="logo-wrapper">
+    <div class="logo-div">
+      <div class="latest">
+        Latest version: <strong><a
+            href="http://docs.gunicorn.org/en/stable">19.9.0</a></strong>
+      </div>
+
+      <div class="logo"><img src="images/logo.jpg" ></div>
+    </div>
+  </div>
+  <div class="banner-wrapper">
+    <div class="banner">
+      <div class="title"><img src="images/title.png"></div>
+      <h1>Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.</h1>
+      <div class="banner-button">
+        <a href="https://github.com/benoitc/gunicorn" title="View source at github" class="greenbutton">View source</a>
+        <a href="http://pypi.python.org/pypi/gunicorn/" title="Download from PyPi" class="redbutton">Download</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="mid-wrapper">
+    <div class="tabs">
+      <ul class="tab-bar">
+        <li class="active">
+          <a href="#quickstart" title="Quickstart" class="gabout">
+            <h2>Quickstart</h2>
+            <p>Read the quickstart guide to get started using Gunicorn.</p>
+          </a>
+        </li>
+        <li class="withborder">
+          <a href="#deployment" title="Deployment" class="gdownloads">
+            <h2>Deployment</h2>
+            <p>Learn how to deploy the Gunicorn server.</p>
+          </a>
+        </li>
+        <li class="withborder">
+          <a href="#community" title="Community" class="gcommunity">
+            <h2>Community</h2>
+            <p>Get in touch with the community.</p>
+          </a>
+        </li>
+        <li class="withborder">
+          <a href="#docs" title="Documentation" class="gdocuments">
+            <h2>Documentation</h2>
+            <p>Read the documentation to learn more about Gunicorn.</p>
+          </a>
+        </li>
+      </ul>
+      <div class="clearall active"></div>
+
+      <div class="tab-box active" data-tab="quickstart">
+        <h1>Installation</h1>
+        <p>
+          Here's a quick rundown on how to get started with Gunicorn. For more details read the <a href="http://docs.gunicorn.org/en/stable/">documentation</a>.
+        </p>
+<pre>
+  $ pip install gunicorn
+  $ cat myapp.py
+    def app(environ, start_response):
+        data = b"Hello, World!\n"
+        start_response("200 OK", [
+            ("Content-Type", "text/plain"),
+            ("Content-Length", str(len(data)))
+        ])
+        return iter([data])
+  $ gunicorn -w 4 myapp:app
+  [2014-09-10 10:22:28 +0000] [30869] [INFO] Listening at: http://127.0.0.1:8000 (30869)
+  [2014-09-10 10:22:28 +0000] [30869] [INFO] Using worker: sync
+  [2014-09-10 10:22:28 +0000] [30874] [INFO] Booting worker with pid: 30874
+  [2014-09-10 10:22:28 +0000] [30875] [INFO] Booting worker with pid: 30875
+  [2014-09-10 10:22:28 +0000] [30876] [INFO] Booting worker with pid: 30876
+  [2014-09-10 10:22:28 +0000] [30877] [INFO] Booting worker with pid: 30877
+</pre>
+      </div>
+      <div class="tab-box" data-tab="deployment">
+        <h1>Deployment</h1>
+        <p>
+          Gunicorn is a WSGI HTTP server. It is best to use Gunicorn behind an HTTP proxy server. We strongly advise you to use <a href="http://www.nginx.org/">nginx</a>.
+        </p>
+        <p>Here's an example to help you get started with using nginx:</p>
+<pre>
+  server {
+    listen 80;
+    server_name example.org;
+    access_log  /var/log/nginx/example.log;
+
+    location / {
+        proxy_pass http://127.0.0.1:8000;
+        proxy_set_header Host $host;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    }
+  }
+</pre>
+        <p>Nginx is set up as reverse proxy server to a Gunicorn server running on localhost port 8000.</p>
+        <p>Read the full documentation at <a
+          href="http://docs.gunicorn.org/en/latest/deploy.html">docs.gunicorn.org</a></p>
+      </div>
+      <div class="tab-box" data-tab="community">
+        <h1>Project Management</h1>
+        <p><strong>Gunicorn</strong> uses <a href="https://github.com/benoitc/gunicorn/projects">GitHub for the project management</a>. GitHub issues are used for 3 different purposes:</p>
+        <ul>
+          <li><a href="https://github.com/benoitc/gunicorn/projects/2">Bug tracker</a></li>
+          <li><a href="https://github.com/benoitc/gunicorn/projects/4">Forum</a></li>
+          <li><a href="https://github.com/benoitc/gunicorn/projects/3">Mailing list</a>
+        </ul>
+        <p>Project maintenance guidelines are avaible on the <a href="https://github.com/benoitc/gunicorn/wiki/Project-management">wiki</a></p>
+        
+        <h1>Irc</h1>
+        <p>The Gunicorn channel is on the <a href="http://freenode.net/">Freenode</a> IRC
+          network. You can chat with the community on the <a href="http://webchat.freenode.net/?channels=gunicorn">#gunicorn channel</a>.</p>
+
+        <h1>Issue Tracking</h1>
+        <p>Bug reports, enhancement requests and tasks generally go in the <a  href="http://github.com/benoitc/gunicorn/issues">Github
+          issue tracker</a>.</p>
+
+        <h1>Security Issues</h1>
+        <p>The security mailing list is a place to report security issues. Only
+        developers are subscribed to it. To post a message to the list use the
+        address <a  href="mailto:security&#64;gunicorn.org">security&#64;gunicorn.org</a></p>
+
+      </div>
+      <div class="tab-box" data-tab="docs">
+        <h1>Documentation</h1>
+        <p>You can read more comprehensive documentation at <a href="http://docs.gunicorn.org">docs.gunicorn.org</a>.</p>
+        <p>The contents are:</p>
+        <ul>
+          <li><a href="http://docs.gunicorn.org/en/latest/install.html">Installation</a></li>
+          <li><a
+            href="http://docs.gunicorn.org/en/latest/run.html">Running
+            Gunicorn</a></li>
+          <li><a
+            href="http://docs.gunicorn.org/en/latest/configure.html">Configuration
+            Overview</a></li>
+          <li><a href="http://docs.gunicorn.org/en/latest/deploy.html">Deploying Gunicorn</a></li>
+          <li><a href="http://docs.gunicorn.org/en/latest/design.html">Design</a></li>
+          <li><a href="http://docs.gunicorn.org/en/latest/faq.html">FAQ</a></li>
+          <li><a href="http://docs.gunicorn.org/en/latest/news.html">Changelog</a></li>
+      </div>
+    </div>
+  </div>
+
+  <!-- <div class="user-wrapper">
+    <div class="users">
+      <div class="left-details">
+        <h3>Who is using</h3>
+        <h2>Gunicorn</h2>
+      </div>
+      <div class="company-logos">
+        <a href="#"><img src="images/user1.jpg"></a>
+        <a href="#"><img src="images/user1.jpg"></a>
+        <a href="#"><img src="images/user1.jpg"></a>
+        <a href="#"><img src="images/user1.jpg"></a>
+        <a href="#"><img src="images/user1.jpg"></a>
+        <a href="#"><img src="images/user1.jpg"></a>
+      </div>
+      <div class="clearall"></div>
+    </div>
+  </div> -->
+
+  <div class="footer">
+    <div class="footer-wp">
+      This open sourced site is hosted on GitHub. <br>
+      <a href="http://github.com/benoitc/gunicorn/issues">Patches, suggestions, and comments are welcome.</a>
+    </div>
+  </div>
+
+  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
+  <script src="js/main.js"></script>
+</body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/install.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Install</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/installation.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Install</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 46 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/js/main.js

@@ -0,0 +1,46 @@
+$(document).ready(function() {
+  Tabs.init();
+});
+
+var Tabs = {
+    init: function(){
+        var activateTab = function ($tab) {
+            var // this links tabs set
+                $tabs = $tab.parents('.tabs'),
+                // currently active tab
+                activeTab = {
+                    'tab' : $tabs.find('ul').children('li.active'),
+                    'content' : $tabs.find('div[data-tab].active')
+                },
+                // newly clicked tab
+                newTab = {
+                    'tab' : $tab.parent('li'),
+                    'content' : $tabs.find('[data-tab=' + $tab.attr('href').replace('#', '') + ']')
+                },
+                x, y;
+
+            // remove active class from tab and content
+            for (x in activeTab) {
+                activeTab[x].removeClass('active');
+            }
+
+            // add active class to tab and content
+            for (y in newTab) {
+                newTab[y].addClass('active');
+            }
+        };
+        // hook up tab links
+        $(document).on('click', '.tabs ul li a', function(e) {
+            activateTab($(this));
+            //alert($(this));
+        });
+
+        // hook up initial load active tab
+        if (window.location.hash) {
+            var $activeTab = $('a[href="'  +  window.location.hash  +  '"]');
+            if ($activeTab.length && $activeTab.parents('.tabs').length) {
+                activateTab($activeTab);
+            }
+        }
+    }
+};

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/news.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - News</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/run.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Run</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 112 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/sitemap.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset
+  xmlns="http://www.google.com/schemas/sitemap/0.84"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84
+                      http://www.google.com/schemas/sitemap/0.84/sitemap.xsd">
+ <url>
+  <loc>http://gunicorn.org/</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/configuration.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/configure.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/css/</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/css/index.css</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/css/style.css</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/deploy.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/deployment.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/design.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/faq.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/images/</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/images/gunicorn.png</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/images/large_gunicorn.png</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/images/logo.png</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/index.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/install.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/installation.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/news.html</loc>
+  <lastmod>2010-07-08T19:57:19Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/run.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/tuning.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+ <url>
+  <loc>http://gunicorn.org/usage.html</loc>
+  <lastmod>2010-07-01T05:14:22Z</lastmod>
+  <priority>0.5000</priority>
+ </url>
+</urlset>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/tuning.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - FAQ</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 13 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/site/usage.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
+    <title>Green Unicorn - Run</title>
+  </head>
+  <body>
+    <h2>
+      Redirecting to <a href="http://gunicorn.org/">here</a>
+    </h2>
+  </body>
+</html>

+ 19 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/sitemap_config.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site
+ base_url="http://gunicorn.org"
+ store_into="htdocs/sitemap.xml"
+ verbose="1"
+>
+
+<directory  path="htdocs/" url="http://gunicorn.org/" />
+
+<!-- Exclude URLs that end with a '~'   (IE: emacs backup files)      -->
+<filter  action="drop"  type="wildcard"  pattern="*~" />
+
+<!-- Exclude URLs within UNIX-style hidden files or directories       -->
+<filter  action="drop"  type="regexp"    pattern="/\.[^/]*" />
+
+<!-- Exclude github CNAME file -->
+<filter  action="drop"  type="wildcard"  pattern="*CNAME" />
+
+</site>

+ 2205 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/sitemap_gen.py

@@ -0,0 +1,2205 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2004, 2005 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+#
+# * Neither the name of Google nor the names of its contributors may
+#   be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+#
+# The sitemap_gen.py script is written in Python 2.2 and released to
+# the open source community for continuous improvements under the BSD
+# 2.0 new license, which can be found at:
+#
+#   http://www.opensource.org/licenses/bsd-license.php
+#
+
+__usage__ = \
+"""A simple script to automatically produce sitemaps for a webserver,
+in the Google Sitemap Protocol (GSP).
+
+Usage: python sitemap_gen.py --config=config.xml [--help] [--testing]
+            --config=config.xml, specifies config file location
+            --help, displays usage message
+            --testing, specified when user is experimenting
+"""
+
+# Please be careful that all syntax used in this file can be parsed on
+# Python 1.5 -- this version check is not evaluated until after the
+# entire file has been parsed.
+import sys
+if sys.hexversion < 0x02020000:
+  print 'This script requires Python 2.2 or later.'
+  print 'Currently run with version: %s' % sys.version
+  sys.exit(1)
+
+import fnmatch
+import glob
+import gzip
+import hashlib
+import os
+import re
+import stat
+import time
+import types
+import urllib
+import urlparse
+import xml.sax
+
+# True and False were introduced in Python2.2.2
+try:
+  testTrue=True
+  del testTrue
+except NameError:
+  True=1
+  False=0
+
+# Text encodings
+ENC_ASCII = 'ASCII'
+ENC_UTF8  = 'UTF-8'
+ENC_IDNA  = 'IDNA'
+ENC_ASCII_LIST = ['ASCII', 'US-ASCII', 'US', 'IBM367', 'CP367', 'ISO646-US'
+                  'ISO_646.IRV:1991', 'ISO-IR-6', 'ANSI_X3.4-1968',
+                  'ANSI_X3.4-1986', 'CPASCII' ]
+ENC_DEFAULT_LIST = ['ISO-8859-1', 'ISO-8859-2', 'ISO-8859-5']
+
+# Maximum number of urls in each sitemap, before next Sitemap is created
+MAXURLS_PER_SITEMAP = 50000
+
+# Suffix on a Sitemap index file
+SITEINDEX_SUFFIX = '_index.xml'
+
+# Regular expressions tried for extracting URLs from access logs.
+ACCESSLOG_CLF_PATTERN = re.compile(
+  r'.+\s+"([^\s]+)\s+([^\s]+)\s+HTTP/\d+\.\d+"\s+200\s+.*'
+  )
+
+# Match patterns for lastmod attributes
+LASTMOD_PATTERNS = map(re.compile, [
+  r'^\d\d\d\d$',
+  r'^\d\d\d\d-\d\d$',
+  r'^\d\d\d\d-\d\d-\d\d$',
+  r'^\d\d\d\d-\d\d-\d\dT\d\d:\d\dZ$',
+  r'^\d\d\d\d-\d\d-\d\dT\d\d:\d\d[+-]\d\d:\d\d$',
+  r'^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?Z$',
+  r'^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?[+-]\d\d:\d\d$',
+  ])
+
+# Match patterns for changefreq attributes
+CHANGEFREQ_PATTERNS = [
+  'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'
+  ]
+
+# XML formats
+SITEINDEX_HEADER   = \
+  '<?xml version="1.0" encoding="UTF-8"?>\n' \
+  '<sitemapindex\n' \
+  '  xmlns="http://www.google.com/schemas/sitemap/0.84"\n' \
+  '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n' \
+  '  xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84\n' \
+  '                      http://www.google.com/schemas/sitemap/0.84/' \
+  'siteindex.xsd">\n'
+SITEINDEX_FOOTER   = '</sitemapindex>\n'
+SITEINDEX_ENTRY    = \
+  ' <sitemap>\n' \
+  '  <loc>%(loc)s</loc>\n' \
+  '  <lastmod>%(lastmod)s</lastmod>\n' \
+  ' </sitemap>\n'
+SITEMAP_HEADER     = \
+  '<?xml version="1.0" encoding="UTF-8"?>\n' \
+  '<urlset\n' \
+  '  xmlns="http://www.google.com/schemas/sitemap/0.84"\n' \
+  '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n' \
+  '  xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84\n' \
+  '                      http://www.google.com/schemas/sitemap/0.84/' \
+  'sitemap.xsd">\n'
+SITEMAP_FOOTER     = '</urlset>\n'
+SITEURL_XML_PREFIX = ' <url>\n'
+SITEURL_XML_SUFFIX = ' </url>\n'
+
+# Search engines to notify with the updated sitemaps
+#
+# This list is very non-obvious in what's going on.  Here's the gist:
+# Each item in the list is a 6-tuple of items.  The first 5 are "almost"
+# the same as the input arguments to urlparse.urlunsplit():
+#   0 - schema
+#   1 - netloc
+#   2 - path
+#   3 - query    <-- EXCEPTION: specify a query map rather than a string
+#   4 - fragment
+# Additionally, add item 5:
+#   5 - query attribute that should be set to the new Sitemap URL
+# Clear as mud, I know.
+NOTIFICATION_SITES = [
+  ('http', 'www.google.com', 'webmasters/sitemaps/ping', {}, '', 'sitemap')
+  ]
+
+
+class Error(Exception):
+  """
+  Base exception class.  In this module we tend not to use our own exception
+  types for very much, but they come in very handy on XML parsing with SAX.
+  """
+  pass
+#end class Error
+
+
+class SchemaError(Error):
+  """Failure to process an XML file according to the schema we know."""
+  pass
+#end class SchemeError
+
+
+class Encoder:
+  """
+  Manages wide-character/narrow-character conversions for just about all
+  text that flows into or out of the script.
+
+  You should always use this class for string coercion, as opposed to
+  letting Python handle coercions automatically.  Reason: Python
+  usually assumes ASCII (7-bit) as a default narrow character encoding,
+  which is not the kind of data we generally deal with.
+
+  General high-level methodologies used in sitemap_gen:
+
+  [PATHS]
+  File system paths may be wide or narrow, depending on platform.
+  This works fine, just be aware of it and be very careful to not
+  mix them.  That is, if you have to pass several file path arguments
+  into a library call, make sure they are all narrow or all wide.
+  This class has MaybeNarrowPath() which should be called on every
+  file system path you deal with.
+
+  [URLS]
+  URL locations are stored in Narrow form, already escaped.  This has the
+  benefit of keeping escaping and encoding as close as possible to the format
+  we read them in.  The downside is we may end up with URLs that have
+  intermingled encodings -- the root path may be encoded in one way
+  while the filename is encoded in another.  This is obviously wrong, but
+  it should hopefully be an issue hit by very few users.  The workaround
+  from the user level (assuming they notice) is to specify a default_encoding
+  parameter in their config file.
+
+  [OTHER]
+  Other text, such as attributes of the URL class, configuration options,
+  etc, are generally stored in Unicode for simplicity.
+  """
+
+  def __init__(self):
+    self._user      = None                  # User-specified default encoding
+    self._learned   = []                    # Learned default encodings
+    self._widefiles = False                 # File system can be wide
+
+    # Can the file system be Unicode?
+    try:
+      self._widefiles = os.path.supports_unicode_filenames
+    except AttributeError:
+      try:
+        self._widefiles = sys.getwindowsversion() == os.VER_PLATFORM_WIN32_NT
+      except AttributeError:
+        pass
+
+    # Try to guess a working default
+    try:
+      encoding = sys.getfilesystemencoding()
+      if encoding and not (encoding.upper() in ENC_ASCII_LIST):
+        self._learned = [ encoding ]
+    except AttributeError:
+      pass
+
+    if not self._learned:
+      encoding = sys.getdefaultencoding()
+      if encoding and not (encoding.upper() in ENC_ASCII_LIST):
+        self._learned = [ encoding ]
+
+    # If we had no guesses, start with some European defaults
+    if not self._learned:
+      self._learned = ENC_DEFAULT_LIST
+  #end def __init__
+
+  def SetUserEncoding(self, encoding):
+    self._user = encoding
+  #end def SetUserEncoding
+
+  def NarrowText(self, text, encoding):
+    """ Narrow a piece of arbitrary text """
+    if type(text) != types.UnicodeType:
+      return text
+
+    # Try the passed in preference
+    if encoding:
+      try:
+        result = text.encode(encoding)
+        if not encoding in self._learned:
+          self._learned.append(encoding)
+        return result
+      except UnicodeError:
+        pass
+      except LookupError:
+        output.Warn('Unknown encoding: %s' % encoding)
+
+    # Try the user preference
+    if self._user:
+      try:
+        return text.encode(self._user)
+      except UnicodeError:
+        pass
+      except LookupError:
+        temp = self._user
+        self._user = None
+        output.Warn('Unknown default_encoding: %s' % temp)
+
+    # Look through learned defaults, knock any failing ones out of the list
+    while self._learned:
+      try:
+        return text.encode(self._learned[0])
+      except:
+        del self._learned[0]
+
+    # When all other defaults are exhausted, use UTF-8
+    try:
+      return text.encode(ENC_UTF8)
+    except UnicodeError:
+      pass
+
+    # Something is seriously wrong if we get to here
+    return text.encode(ENC_ASCII, 'ignore')
+  #end def NarrowText
+
+  def MaybeNarrowPath(self, text):
+    """ Paths may be allowed to stay wide """
+    if self._widefiles:
+      return text
+    return self.NarrowText(text, None)
+  #end def MaybeNarrowPath
+
+  def WidenText(self, text, encoding):
+    """ Widen a piece of arbitrary text """
+    if type(text) != types.StringType:
+      return text
+
+    # Try the passed in preference
+    if encoding:
+      try:
+        result = unicode(text, encoding)
+        if not encoding in self._learned:
+          self._learned.append(encoding)
+        return result
+      except UnicodeError:
+        pass
+      except LookupError:
+        output.Warn('Unknown encoding: %s' % encoding)
+
+    # Try the user preference
+    if self._user:
+      try:
+        return unicode(text, self._user)
+      except UnicodeError:
+        pass
+      except LookupError:
+        temp = self._user
+        self._user = None
+        output.Warn('Unknown default_encoding: %s' % temp)
+
+    # Look through learned defaults, knock any failing ones out of the list
+    while self._learned:
+      try:
+        return unicode(text, self._learned[0])
+      except:
+        del self._learned[0]
+
+    # When all other defaults are exhausted, use UTF-8
+    try:
+      return unicode(text, ENC_UTF8)
+    except UnicodeError:
+      pass
+
+    # Getting here means it wasn't UTF-8 and we had no working default.
+    # We really don't have anything "right" we can do anymore.
+    output.Warn('Unrecognized encoding in text: %s' % text)
+    if not self._user:
+      output.Warn('You may need to set a default_encoding in your '
+                  'configuration file.')
+    return text.decode(ENC_ASCII, 'ignore')
+  #end def WidenText
+#end class Encoder
+encoder = Encoder()
+
+
+class Output:
+  """
+  Exposes logging functionality, and tracks how many errors
+  we have thus output.
+
+  Logging levels should be used as thus:
+    Fatal     -- extremely sparingly
+    Error     -- config errors, entire blocks of user 'intention' lost
+    Warn      -- individual URLs lost
+    Log(,0)   -- Un-suppressable text that's not an error
+    Log(,1)   -- touched files, major actions
+    Log(,2)   -- parsing notes, filtered or duplicated URLs
+    Log(,3)   -- each accepted URL
+  """
+
+  def __init__(self):
+    self.num_errors    = 0                   # Count of errors
+    self.num_warns     = 0                   # Count of warnings
+
+    self._errors_shown = {}                  # Shown errors
+    self._warns_shown  = {}                  # Shown warnings
+    self._verbose      = 0                   # Level of verbosity
+  #end def __init__
+
+  def Log(self, text, level):
+    """ Output a blurb of diagnostic text, if the verbose level allows it """
+    if text:
+      text = encoder.NarrowText(text, None)
+      if self._verbose >= level:
+        print text
+  #end def Log
+
+  def Warn(self, text):
+    """ Output and count a warning.  Suppress duplicate warnings. """
+    if text:
+      text = encoder.NarrowText(text, None)
+      hash = hashlib.md5(text).hexdigest()
+      if not self._warns_shown.has_key(hash):
+        self._warns_shown[hash] = 1
+        print '[WARNING] ' + text
+      else:
+        self.Log('(suppressed) [WARNING] ' + text, 3)
+      self.num_warns = self.num_warns + 1
+  #end def Warn
+
+  def Error(self, text):
+    """ Output and count an error.  Suppress duplicate errors. """
+    if text:
+      text = encoder.NarrowText(text, None)
+      hash = hashlib.md5(text).hexdigest()
+      if not self._errors_shown.has_key(hash):
+        self._errors_shown[hash] = 1
+        print '[ERROR] ' + text
+      else:
+        self.Log('(suppressed) [ERROR] ' + text, 3)
+      self.num_errors = self.num_errors + 1
+  #end def Error
+
+  def Fatal(self, text):
+    """ Output an error and terminate the program. """
+    if text:
+      text = encoder.NarrowText(text, None)
+      print '[FATAL] ' + text
+    else:
+      print 'Fatal error.'
+    sys.exit(1)
+  #end def Fatal
+
+  def SetVerbose(self, level):
+    """ Sets the verbose level. """
+    try:
+      if type(level) != types.IntType:
+        level = int(level)
+      if (level >= 0) and (level <= 3):
+        self._verbose = level
+        return
+    except ValueError:
+      pass
+    self.Error('Verbose level (%s) must be between 0 and 3 inclusive.' % level)
+  #end def SetVerbose
+#end class Output
+output = Output()
+
+
+class URL(object):
+  """ URL is a smart structure grouping together the properties we
+  care about for a single web reference. """
+  __slots__ = 'loc', 'lastmod', 'changefreq', 'priority'
+
+  def __init__(self):
+    self.loc        = None                  # URL -- in Narrow characters
+    self.lastmod    = None                  # ISO8601 timestamp of last modify
+    self.changefreq = None                  # Text term for update frequency
+    self.priority   = None                  # Float between 0 and 1 (inc)
+  #end def __init__
+
+  def __cmp__(self, other):
+    if self.loc < other.loc:
+      return -1
+    if self.loc > other.loc:
+      return 1
+    return 0
+  #end def __cmp__
+
+  def TrySetAttribute(self, attribute, value):
+    """ Attempt to set the attribute to the value, with a pretty try
+    block around it.  """
+    if attribute == 'loc':
+      self.loc = self.Canonicalize(value)
+    else:
+      try:
+        setattr(self, attribute, value)
+      except AttributeError:
+        output.Warn('Unknown URL attribute: %s' % attribute)
+  #end def TrySetAttribute
+
+  def IsAbsolute(loc):
+    """ Decide if the URL is absolute or not """
+    if not loc:
+      return False
+    narrow = encoder.NarrowText(loc, None)
+    (scheme, netloc, path, query, frag) = urlparse.urlsplit(narrow)
+    if (not scheme) or (not netloc):
+      return False
+    return True
+  #end def IsAbsolute
+  IsAbsolute = staticmethod(IsAbsolute)
+
+  def Canonicalize(loc):
+    """ Do encoding and canonicalization on a URL string """
+    if not loc:
+      return loc
+
+    # Let the encoder try to narrow it
+    narrow = encoder.NarrowText(loc, None)
+
+    # Escape components individually
+    (scheme, netloc, path, query, frag) = urlparse.urlsplit(narrow)
+    unr    = '-._~'
+    sub    = '!$&\'()*+,;='
+    netloc = urllib.quote(netloc, unr + sub + '%:@/[]')
+    path   = urllib.quote(path,   unr + sub + '%:@/')
+    query  = urllib.quote(query,  unr + sub + '%:@/?')
+    frag   = urllib.quote(frag,   unr + sub + '%:@/?')
+
+    # Try built-in IDNA encoding on the netloc
+    try:
+      (ignore, widenetloc, ignore, ignore, ignore) = urlparse.urlsplit(loc)
+      for c in widenetloc:
+        if c >= unichr(128):
+          netloc = widenetloc.encode(ENC_IDNA)
+          netloc = urllib.quote(netloc, unr + sub + '%:@/[]')
+          break
+    except UnicodeError:
+      # urlsplit must have failed, based on implementation differences in the
+      # library.  There is not much we can do here, except ignore it.
+      pass
+    except LookupError:
+      output.Warn('An International Domain Name (IDN) is being used, but this '
+                  'version of Python does not have support for IDNA encoding. '
+                  ' (IDNA support was introduced in Python 2.3)  The encoding '
+                  'we have used instead is wrong and will probably not yield '
+                  'valid URLs.')
+    bad_netloc = False
+    if '%' in netloc:
+      bad_netloc = True
+
+    # Put it all back together
+    narrow = urlparse.urlunsplit((scheme, netloc, path, query, frag))
+
+    # I let '%' through.  Fix any that aren't pre-existing escapes.
+    HEXDIG = '0123456789abcdefABCDEF'
+    list   = narrow.split('%')
+    narrow = list[0]
+    del list[0]
+    for item in list:
+      if (len(item) >= 2) and (item[0] in HEXDIG) and (item[1] in HEXDIG):
+        narrow = narrow + '%' + item
+      else:
+        narrow = narrow + '%25' + item
+
+    # Issue a warning if this is a bad URL
+    if bad_netloc:
+      output.Warn('Invalid characters in the host or domain portion of a URL: '
+                  + narrow)
+
+    return narrow
+  #end def Canonicalize
+  Canonicalize = staticmethod(Canonicalize)
+
+  def Validate(self, base_url, allow_fragment):
+    """ Verify the data in this URL is well-formed, and override if not. """
+    assert type(base_url) == types.StringType
+
+    # Test (and normalize) the ref
+    if not self.loc:
+      output.Warn('Empty URL')
+      return False
+    if allow_fragment:
+      self.loc = urlparse.urljoin(base_url, self.loc)
+    if not self.loc.startswith(base_url):
+      output.Warn('Discarded URL for not starting with the base_url: %s' %
+                  self.loc)
+      self.loc = None
+      return False
+
+    # Test the lastmod
+    if self.lastmod:
+      match = False
+      self.lastmod = self.lastmod.upper()
+      for pattern in LASTMOD_PATTERNS:
+        match = pattern.match(self.lastmod)
+        if match:
+          break
+      if not match:
+        output.Warn('Lastmod "%s" does not appear to be in ISO8601 format on '
+                    'URL: %s' % (self.lastmod, self.loc))
+        self.lastmod = None
+
+    # Test the changefreq
+    if self.changefreq:
+      match = False
+      self.changefreq = self.changefreq.lower()
+      for pattern in CHANGEFREQ_PATTERNS:
+        if self.changefreq == pattern:
+          match = True
+          break
+      if not match:
+        output.Warn('Changefreq "%s" is not a valid change frequency on URL '
+                    ': %s' % (self.changefreq, self.loc))
+        self.changefreq = None
+
+    # Test the priority
+    if self.priority:
+      priority = -1.0
+      try:
+        priority = float(self.priority)
+      except ValueError:
+        pass
+      if (priority < 0.0) or (priority > 1.0):
+        output.Warn('Priority "%s" is not a number between 0 and 1 inclusive '
+                    'on URL: %s' % (self.priority, self.loc))
+        self.priority = None
+
+    return True
+  #end def Validate
+
+  def MakeHash(self):
+    """ Provides a uniform way of hashing URLs """
+    if not self.loc:
+      return None
+    if self.loc.endswith('/'):
+      return hashlib.md5(self.loc[:-1]).hexdigest()
+    return hashlib.md5(self.loc).hexdigest()
+  #end def MakeHash
+
+  def Log(self, prefix='URL', level=3):
+    """ Dump the contents, empty or not, to the log. """
+    out = prefix + ':'
+
+    for attribute in self.__slots__:
+      value = getattr(self, attribute)
+      if not value:
+        value = ''
+      out = out + ('  %s=[%s]' % (attribute, value))
+
+    output.Log('%s' % encoder.NarrowText(out, None), level)
+  #end def Log
+
+  def WriteXML(self, file):
+    """ Dump non-empty contents to the output file, in XML format. """
+    if not self.loc:
+      return
+    out = SITEURL_XML_PREFIX
+
+    for attribute in self.__slots__:
+      value = getattr(self, attribute)
+      if value:
+        if type(value) == types.UnicodeType:
+          value = encoder.NarrowText(value, None)
+        elif type(value) != types.StringType:
+          value = str(value)
+        value = xml.sax.saxutils.escape(value)
+        out = out + ('  <%s>%s</%s>\n' % (attribute, value, attribute))
+
+    out = out + SITEURL_XML_SUFFIX
+    file.write(out)
+  #end def WriteXML
+#end class URL
+
+
+class Filter:
+  """
+  A filter on the stream of URLs we find.  A filter is, in essence,
+  a wildcard applied to the stream.  You can think of this as an
+  operator that returns a tri-state when given a URL:
+
+    True  -- this URL is to be included in the sitemap
+    None  -- this URL is undecided
+    False -- this URL is to be dropped from the sitemap
+  """
+
+  def __init__(self, attributes):
+    self._wildcard  = None                  # Pattern for wildcard match
+    self._regexp    = None                  # Pattern for regexp match
+    self._pass      = False                 # "Drop" filter vs. "Pass" filter
+
+    if not ValidateAttributes('FILTER', attributes,
+                              ('pattern', 'type', 'action')):
+      return
+
+    # Check error count on the way in
+    num_errors = output.num_errors
+
+    # Fetch the attributes
+    pattern = attributes.get('pattern')
+    type    = attributes.get('type', 'wildcard')
+    action  = attributes.get('action', 'drop')
+    if type:
+      type = type.lower()
+    if action:
+      action = action.lower()
+
+    # Verify the attributes
+    if not pattern:
+      output.Error('On a filter you must specify a "pattern" to match')
+    elif (not type) or ((type != 'wildcard') and (type != 'regexp')):
+      output.Error('On a filter you must specify either \'type="wildcard"\' '
+                   'or \'type="regexp"\'')
+    elif (action != 'pass') and (action != 'drop'):
+      output.Error('If you specify a filter action, it must be either '
+                   '\'action="pass"\' or \'action="drop"\'')
+
+    # Set the rule
+    if action == 'drop':
+      self._pass = False
+    elif action == 'pass':
+      self._pass = True
+
+    if type == 'wildcard':
+      self._wildcard = pattern
+    elif type == 'regexp':
+      try:
+        self._regexp = re.compile(pattern)
+      except re.error:
+        output.Error('Bad regular expression: %s' %  pattern)
+
+    # Log the final results iff we didn't add any errors
+    if num_errors == output.num_errors:
+      output.Log('Filter: %s any URL that matches %s "%s"' %
+                 (action, type, pattern), 2)
+  #end def __init__
+
+  def Apply(self, url):
+    """ Process the URL, as above. """
+    if (not url) or (not url.loc):
+      return None
+
+    if self._wildcard:
+      if fnmatch.fnmatchcase(url.loc, self._wildcard):
+        return self._pass
+      return None
+
+    if self._regexp:
+      if self._regexp.search(url.loc):
+        return self._pass
+      return None
+
+    assert False # unreachable
+  #end def Apply
+#end class Filter
+
+
+class InputURL:
+  """
+  Each Input class knows how to yield a set of URLs from a data source.
+
+  This one handles a single URL, manually specified in the config file.
+  """
+
+  def __init__(self, attributes):
+    self._url = None                        # The lonely URL
+
+    if not ValidateAttributes('URL', attributes,
+                                ('href', 'lastmod', 'changefreq', 'priority')):
+      return
+
+    url = URL()
+    for attr in attributes.keys():
+      if attr == 'href':
+        url.TrySetAttribute('loc', attributes[attr])
+      else:
+        url.TrySetAttribute(attr, attributes[attr])
+
+    if not url.loc:
+      output.Error('Url entries must have an href attribute.')
+      return
+
+    self._url = url
+    output.Log('Input: From URL "%s"' % self._url.loc, 2)
+  #end def __init__
+
+  def ProduceURLs(self, consumer):
+    """ Produces URLs from our data source, hands them in to the consumer. """
+    if self._url:
+      consumer(self._url, True)
+  #end def ProduceURLs
+#end class InputURL
+
+
+class InputURLList:
+  """
+  Each Input class knows how to yield a set of URLs from a data source.
+
+  This one handles a text file with a list of URLs
+  """
+
+  def __init__(self, attributes):
+    self._path      = None                  # The file path
+    self._encoding  = None                  # Encoding of that file
+
+    if not ValidateAttributes('URLLIST', attributes, ('path', 'encoding')):
+      return
+
+    self._path      = attributes.get('path')
+    self._encoding  = attributes.get('encoding', ENC_UTF8)
+    if self._path:
+      self._path    = encoder.MaybeNarrowPath(self._path)
+      if os.path.isfile(self._path):
+        output.Log('Input: From URLLIST "%s"' % self._path, 2)
+      else:
+        output.Error('Can not locate file: %s' % self._path)
+        self._path = None
+    else:
+      output.Error('Urllist entries must have a "path" attribute.')
+  #end def __init__
+
+  def ProduceURLs(self, consumer):
+    """ Produces URLs from our data source, hands them in to the consumer. """
+
+    # Open the file
+    (frame, file) = OpenFileForRead(self._path, 'URLLIST')
+    if not file:
+      return
+
+    # Iterate lines
+    linenum = 0
+    for line in file.readlines():
+      linenum = linenum + 1
+
+      # Strip comments and empty lines
+      if self._encoding:
+        line = encoder.WidenText(line, self._encoding)
+      line = line.strip()
+      if (not line) or line[0] == '#':
+        continue
+
+      # Split the line on space
+      url = URL()
+      cols = line.split(' ')
+      for i in range(0,len(cols)):
+        cols[i] = cols[i].strip()
+      url.TrySetAttribute('loc', cols[0])
+
+      # Extract attributes from the other columns
+      for i in range(1,len(cols)):
+        if cols[i]:
+          try:
+            (attr_name, attr_val) = cols[i].split('=', 1)
+            url.TrySetAttribute(attr_name, attr_val)
+          except ValueError:
+            output.Warn('Line %d: Unable to parse attribute: %s' %
+                        (linenum, cols[i]))
+
+      # Pass it on
+      consumer(url, False)
+
+    file.close()
+    if frame:
+      frame.close()
+  #end def ProduceURLs
+#end class InputURLList
+
+
+class InputDirectory:
+  """
+  Each Input class knows how to yield a set of URLs from a data source.
+
+  This one handles a directory that acts as base for walking the filesystem.
+  """
+
+  def __init__(self, attributes, base_url):
+    self._path         = None               # The directory
+    self._url          = None               # The URL equivalent
+    self._default_file = None
+
+    if not ValidateAttributes('DIRECTORY', attributes, ('path', 'url',
+                                                           'default_file')):
+      return
+
+    # Prep the path -- it MUST end in a sep
+    path = attributes.get('path')
+    if not path:
+      output.Error('Directory entries must have both "path" and "url" '
+                  'attributes')
+      return
+    path = encoder.MaybeNarrowPath(path)
+    if not path.endswith(os.sep):
+      path = path + os.sep
+    if not os.path.isdir(path):
+      output.Error('Can not locate directory: %s' % path)
+      return
+
+    # Prep the URL -- it MUST end in a sep
+    url = attributes.get('url')
+    if not url:
+      output.Error('Directory entries must have both "path" and "url" '
+                  'attributes')
+      return
+    url = URL.Canonicalize(url)
+    if not url.endswith('/'):
+      url = url + '/'
+    if not url.startswith(base_url):
+      url = urlparse.urljoin(base_url, url)
+      if not url.startswith(base_url):
+        output.Error('The directory URL "%s" is not relative to the '
+                    'base_url: %s' % (url, base_url))
+        return
+
+    # Prep the default file -- it MUST be just a filename
+    file = attributes.get('default_file')
+    if file:
+      file = encoder.MaybeNarrowPath(file)
+      if os.sep in file:
+        output.Error('The default_file "%s" can not include path information.'
+                     % file)
+        file = None
+
+    self._path         = path
+    self._url          = url
+    self._default_file = file
+    if file:
+      output.Log('Input: From DIRECTORY "%s" (%s) with default file "%s"'
+                 % (path, url, file), 2)
+    else:
+      output.Log('Input: From DIRECTORY "%s" (%s) with no default file'
+                 % (path, url), 2)
+  #end def __init__
+
+  def ProduceURLs(self, consumer):
+    """ Produces URLs from our data source, hands them in to the consumer. """
+    if not self._path:
+      return
+
+    root_path = self._path
+    root_URL  = self._url
+    root_file = self._default_file
+
+    def PerFile(dirpath, name):
+      """
+      Called once per file.
+      Note that 'name' will occasionally be None -- for a directory itself
+      """
+      # Pull a timestamp
+      url           = URL()
+      isdir         = False
+      try:
+        if name:
+          path      = os.path.join(dirpath, name)
+        else:
+          path      = dirpath
+        isdir       = os.path.isdir(path)
+        time        = None
+        if isdir and root_file:
+          file      = os.path.join(path, root_file)
+          try:
+            time    = os.stat(file)[stat.ST_MTIME];
+          except OSError:
+            pass
+        if not time:
+          time      = os.stat(path)[stat.ST_MTIME];
+        url.lastmod = TimestampISO8601(time)
+      except OSError:
+        pass
+      except ValueError:
+        pass
+
+      # Build a URL
+      middle        = dirpath[len(root_path):]
+      if os.sep != '/':
+        middle = middle.replace(os.sep, '/')
+      if middle:
+        middle      = middle + '/'
+      if name:
+        middle      = middle + name
+        if isdir:
+          middle    = middle + '/'
+      url.TrySetAttribute('loc', root_URL + encoder.WidenText(middle, None))
+
+      # Suppress default files.  (All the way down here so we can log it.)
+      if name and (root_file == name):
+        url.Log(prefix='IGNORED (default file)', level=2)
+        return
+
+      consumer(url, False)
+    #end def PerFile
+
+    def PerDirectory(ignore, dirpath, namelist):
+      """
+      Called once per directory with a list of all the contained files/dirs.
+      """
+      ignore = ignore  # Avoid warnings of an unused parameter
+
+      if not dirpath.startswith(root_path):
+        output.Warn('Unable to decide what the root path is for directory: '
+                    '%s' % dirpath)
+        return
+
+      for name in namelist:
+        PerFile(dirpath, name)
+    #end def PerDirectory
+
+    output.Log('Walking DIRECTORY "%s"' % self._path, 1)
+    PerFile(self._path, None)
+    os.path.walk(self._path, PerDirectory, None)
+  #end def ProduceURLs
+#end class InputDirectory
+
+
+class InputAccessLog:
+  """
+  Each Input class knows how to yield a set of URLs from a data source.
+
+  This one handles access logs.  It's non-trivial in that we want to
+  auto-detect log files in the Common Logfile Format (as used by Apache,
+  for instance) and the Extended Log File Format (as used by IIS, for
+  instance).
+  """
+
+  def __init__(self, attributes):
+    self._path         = None               # The file path
+    self._encoding     = None               # Encoding of that file
+    self._is_elf       = False              # Extended Log File Format?
+    self._is_clf       = False              # Common Logfile Format?
+    self._elf_status   = -1                 # ELF field: '200'
+    self._elf_method   = -1                 # ELF field: 'HEAD'
+    self._elf_uri      = -1                 # ELF field: '/foo?bar=1'
+    self._elf_urifrag1 = -1                 # ELF field: '/foo'
+    self._elf_urifrag2 = -1                 # ELF field: 'bar=1'
+
+    if not ValidateAttributes('ACCESSLOG', attributes, ('path', 'encoding')):
+      return
+
+    self._path      = attributes.get('path')
+    self._encoding  = attributes.get('encoding', ENC_UTF8)
+    if self._path:
+      self._path    = encoder.MaybeNarrowPath(self._path)
+      if os.path.isfile(self._path):
+        output.Log('Input: From ACCESSLOG "%s"' % self._path, 2)
+      else:
+        output.Error('Can not locate file: %s' % self._path)
+        self._path = None
+    else:
+      output.Error('Accesslog entries must have a "path" attribute.')
+  #end def __init__
+
+  def RecognizeELFLine(self, line):
+    """ Recognize the Fields directive that heads an ELF file """
+    if not line.startswith('#Fields:'):
+      return False
+    fields = line.split(' ')
+    del fields[0]
+    for i in range(0, len(fields)):
+      field = fields[i].strip()
+      if field == 'sc-status':
+        self._elf_status   = i
+      elif field == 'cs-method':
+        self._elf_method   = i
+      elif field == 'cs-uri':
+        self._elf_uri      = i
+      elif field == 'cs-uri-stem':
+        self._elf_urifrag1 = i
+      elif field == 'cs-uri-query':
+        self._elf_urifrag2 = i
+    output.Log('Recognized an Extended Log File Format file.', 2)
+    return True
+  #end def RecognizeELFLine
+
+  def GetELFLine(self, line):
+    """ Fetch the requested URL from an ELF line """
+    fields = line.split(' ')
+    count  = len(fields)
+
+    # Verify status was Ok
+    if self._elf_status >= 0:
+      if self._elf_status >= count:
+        return None
+      if not fields[self._elf_status].strip() == '200':
+        return None
+
+    # Verify method was HEAD or GET
+    if self._elf_method >= 0:
+      if self._elf_method >= count:
+        return None
+      if not fields[self._elf_method].strip() in ('HEAD', 'GET'):
+        return None
+
+    # Pull the full URL if we can
+    if self._elf_uri >= 0:
+      if self._elf_uri >= count:
+        return None
+      url = fields[self._elf_uri].strip()
+      if url != '-':
+        return url
+
+    # Put together a fragmentary URL
+    if self._elf_urifrag1 >= 0:
+      if self._elf_urifrag1 >= count or self._elf_urifrag2 >= count:
+        return None
+      urlfrag1 = fields[self._elf_urifrag1].strip()
+      urlfrag2 = None
+      if self._elf_urifrag2 >= 0:
+        urlfrag2 = fields[self._elf_urifrag2]
+      if urlfrag1 and (urlfrag1 != '-'):
+        if urlfrag2 and (urlfrag2 != '-'):
+          urlfrag1 = urlfrag1 + '?' + urlfrag2
+        return urlfrag1
+
+    return None
+  #end def GetELFLine
+
+  def RecognizeCLFLine(self, line):
+    """ Try to tokenize a logfile line according to CLF pattern and see if
+    it works. """
+    match = ACCESSLOG_CLF_PATTERN.match(line)
+    recognize = match and (match.group(1) in ('HEAD', 'GET'))
+    if recognize:
+      output.Log('Recognized a Common Logfile Format file.', 2)
+    return recognize
+  #end def RecognizeCLFLine
+
+  def GetCLFLine(self, line):
+    """ Fetch the requested URL from a CLF line """
+    match = ACCESSLOG_CLF_PATTERN.match(line)
+    if match:
+      request = match.group(1)
+      if request in ('HEAD', 'GET'):
+        return match.group(2)
+    return None
+  #end def GetCLFLine
+
+  def ProduceURLs(self, consumer):
+    """ Produces URLs from our data source, hands them in to the consumer. """
+
+    # Open the file
+    (frame, file) = OpenFileForRead(self._path, 'ACCESSLOG')
+    if not file:
+      return
+
+    # Iterate lines
+    for line in file.readlines():
+      if self._encoding:
+        line = encoder.WidenText(line, self._encoding)
+      line = line.strip()
+
+      # If we don't know the format yet, try them both
+      if (not self._is_clf) and (not self._is_elf):
+        self._is_elf = self.RecognizeELFLine(line)
+        self._is_clf = self.RecognizeCLFLine(line)
+
+      # Digest the line
+      match = None
+      if self._is_elf:
+        match = self.GetELFLine(line)
+      elif self._is_clf:
+        match = self.GetCLFLine(line)
+      if not match:
+        continue
+
+      # Pass it on
+      url = URL()
+      url.TrySetAttribute('loc', match)
+      consumer(url, True)
+
+    file.close()
+    if frame:
+      frame.close()
+  #end def ProduceURLs
+#end class InputAccessLog
+
+
+class InputSitemap(xml.sax.handler.ContentHandler):
+
+  """
+  Each Input class knows how to yield a set of URLs from a data source.
+
+  This one handles Sitemap files and Sitemap index files.  For the sake
+  of simplicity in design (and simplicity in interfacing with the SAX
+  package), we do not handle these at the same time, recursively.  Instead
+  we read an index file completely and make a list of Sitemap files, then
+  go back and process each Sitemap.
+  """
+
+  class _ContextBase(object):
+
+    """Base class for context handlers in our SAX processing.  A context
+    handler is a class that is responsible for understanding one level of
+    depth in the XML schema.  The class knows what sub-tags are allowed,
+    and doing any processing specific for the tag we're in.
+
+    This base class is the API filled in by specific context handlers,
+    all defined below.
+    """
+
+    def __init__(self, subtags):
+      """Initialize with a sequence of the sub-tags that would be valid in
+      this context."""
+      self._allowed_tags = subtags          # Sequence of sub-tags we can have
+      self._last_tag     = None             # Most recent seen sub-tag
+    #end def __init__
+
+    def AcceptTag(self, tag):
+      """Returns True iff opening a sub-tag is valid in this context."""
+      valid = tag in self._allowed_tags
+      if valid:
+        self._last_tag = tag
+      else:
+        self._last_tag = None
+      return valid
+    #end def AcceptTag
+
+    def AcceptText(self, text):
+      """Returns True iff a blurb of text is valid in this context."""
+      return False
+    #end def AcceptText
+
+    def Open(self):
+      """The context is opening.  Do initialization."""
+      pass
+    #end def Open
+
+    def Close(self):
+      """The context is closing.  Return our result, if any."""
+      pass
+    #end def Close
+
+    def Return(self, result):
+      """We're returning to this context after handling a sub-tag.  This
+      method is called with the result data from the sub-tag that just
+      closed.  Here in _ContextBase, if we ever see a result it means
+      the derived child class forgot to override this method."""
+      if result:
+        raise NotImplementedError
+    #end def Return
+  #end class _ContextBase
+
+  class _ContextUrlSet(_ContextBase):
+
+    """Context handler for the document node in a Sitemap."""
+
+    def __init__(self):
+      InputSitemap._ContextBase.__init__(self, ('url',))
+    #end def __init__
+  #end class _ContextUrlSet
+
+  class _ContextUrl(_ContextBase):
+
+    """Context handler for a URL node in a Sitemap."""
+
+    def __init__(self, consumer):
+      """Initialize this context handler with the callable consumer that
+      wants our URLs."""
+      InputSitemap._ContextBase.__init__(self, URL.__slots__)
+      self._url          = None            # The URL object we're building
+      self._consumer     = consumer        # Who wants to consume it
+    #end def __init__
+
+    def Open(self):
+      """Initialize the URL."""
+      assert not self._url
+      self._url = URL()
+    #end def Open
+
+    def Close(self):
+      """Pass the URL to the consumer and reset it to None."""
+      assert self._url
+      self._consumer(self._url, False)
+      self._url = None
+    #end def Close
+
+    def Return(self, result):
+      """A value context has closed, absorb the data it gave us."""
+      assert self._url
+      if result:
+        self._url.TrySetAttribute(self._last_tag, result)
+    #end def Return
+  #end class _ContextUrl
+
+  class _ContextSitemapIndex(_ContextBase):
+
+    """Context handler for the document node in an index file."""
+
+    def __init__(self):
+      InputSitemap._ContextBase.__init__(self, ('sitemap',))
+      self._loclist = []                    # List of accumulated Sitemap URLs
+    #end def __init__
+
+    def Open(self):
+      """Just a quick verify of state."""
+      assert not self._loclist
+    #end def Open
+
+    def Close(self):
+      """Return our list of accumulated URLs."""
+      if self._loclist:
+        temp = self._loclist
+        self._loclist = []
+        return temp
+    #end def Close
+
+    def Return(self, result):
+      """Getting a new loc URL, add it to the collection."""
+      if result:
+        self._loclist.append(result)
+    #end def Return
+  #end class _ContextSitemapIndex
+
+  class _ContextSitemap(_ContextBase):
+
+    """Context handler for a Sitemap entry in an index file."""
+
+    def __init__(self):
+      InputSitemap._ContextBase.__init__(self, ('loc', 'lastmod'))
+      self._loc = None                      # The URL to the Sitemap
+    #end def __init__
+
+    def Open(self):
+      """Just a quick verify of state."""
+      assert not self._loc
+    #end def Open
+
+    def Close(self):
+      """Return our URL to our parent."""
+      if self._loc:
+        temp = self._loc
+        self._loc = None
+        return temp
+      output.Warn('In the Sitemap index file, a "sitemap" entry had no "loc".')
+    #end def Close
+
+    def Return(self, result):
+      """A value has closed.  If it was a 'loc', absorb it."""
+      if result and (self._last_tag == 'loc'):
+        self._loc = result
+    #end def Return
+  #end class _ContextSitemap
+
+  class _ContextValue(_ContextBase):
+
+    """Context handler for a single value.  We return just the value.  The
+    higher level context has to remember what tag led into us."""
+
+    def __init__(self):
+      InputSitemap._ContextBase.__init__(self, ())
+      self._text        = None
+    #end def __init__
+
+    def AcceptText(self, text):
+      """Allow all text, adding it to our buffer."""
+      if self._text:
+        self._text = self._text + text
+      else:
+        self._text = text
+      return True
+    #end def AcceptText
+
+    def Open(self):
+      """Initialize our buffer."""
+      self._text = None
+    #end def Open
+
+    def Close(self):
+      """Return what's in our buffer."""
+      text = self._text
+      self._text = None
+      if text:
+        text = text.strip()
+      return text
+    #end def Close
+  #end class _ContextValue
+
+  def __init__(self, attributes):
+    """Initialize with a dictionary of attributes from our entry in the
+    config file."""
+    xml.sax.handler.ContentHandler.__init__(self)
+    self._pathlist      = None              # A list of files
+    self._current       = -1                # Current context in _contexts
+    self._contexts      = None              # The stack of contexts we allow
+    self._contexts_idx  = None              # ...contexts for index files
+    self._contexts_stm  = None              # ...contexts for Sitemap files
+
+    if not ValidateAttributes('SITEMAP', attributes, ['path']):
+      return
+
+    # Init the first file path
+    path = attributes.get('path')
+    if path:
+      path = encoder.MaybeNarrowPath(path)
+      if os.path.isfile(path):
+        output.Log('Input: From SITEMAP "%s"' % path, 2)
+        self._pathlist = [path]
+      else:
+        output.Error('Can not locate file "%s"' % path)
+    else:
+      output.Error('Sitemap entries must have a "path" attribute.')
+  #end def __init__
+
+  def ProduceURLs(self, consumer):
+    """In general: Produces URLs from our data source, hand them to the
+    callable consumer.
+
+    In specific: Iterate over our list of paths and delegate the actual
+    processing to helper methods.  This is a complexity no other data source
+    needs to suffer.  We are unique in that we can have files that tell us
+    to bring in other files.
+
+    Note the decision to allow an index file or not is made in this method.
+    If we call our parser with (self._contexts == None) the parser will
+    grab whichever context stack can handle the file.  IE: index is allowed.
+    If instead we set (self._contexts = ...) before parsing, the parser
+    will only use the stack we specify.  IE: index not allowed.
+    """
+    # Set up two stacks of contexts
+    self._contexts_idx = [InputSitemap._ContextSitemapIndex(),
+                          InputSitemap._ContextSitemap(),
+                          InputSitemap._ContextValue()]
+
+    self._contexts_stm = [InputSitemap._ContextUrlSet(),
+                          InputSitemap._ContextUrl(consumer),
+                          InputSitemap._ContextValue()]
+
+    # Process the first file
+    assert self._pathlist
+    path = self._pathlist[0]
+    self._contexts = None                # We allow an index file here
+    self._ProcessFile(path)
+
+    # Iterate over remaining files
+    self._contexts = self._contexts_stm  # No index files allowed
+    for path in self._pathlist[1:]:
+      self._ProcessFile(path)
+  #end def ProduceURLs
+
+  def _ProcessFile(self, path):
+    """Do per-file reading/parsing/consuming for the file path passed in."""
+    assert path
+
+    # Open our file
+    (frame, file) = OpenFileForRead(path, 'SITEMAP')
+    if not file:
+      return
+
+    # Rev up the SAX engine
+    try:
+      self._current = -1
+      xml.sax.parse(file, self)
+    except SchemaError:
+      output.Error('An error in file "%s" made us abort reading the Sitemap.'
+                   % path)
+    except IOError:
+      output.Error('Cannot read from file "%s"' % path)
+    except xml.sax._exceptions.SAXParseException, e:
+      output.Error('XML error in the file "%s" (line %d, column %d): %s' %
+                   (path, e._linenum, e._colnum, e.getMessage()))
+
+    # Clean up
+    file.close()
+    if frame:
+      frame.close()
+  #end def _ProcessFile
+
+  def _MungeLocationListIntoFiles(self, urllist):
+    """Given a list of URLs, munge them into our self._pathlist property.
+    We do this by assuming all the files live in the same directory as
+    the first file in the existing pathlist.  That is, we assume a
+    Sitemap index points to Sitemaps only in the same directory.  This
+    is not true in general, but will be true for any output produced
+    by this script.
+    """
+    assert self._pathlist
+    path = self._pathlist[0]
+    path = os.path.normpath(path)
+    dir  = os.path.dirname(path)
+    wide = False
+    if type(path) == types.UnicodeType:
+      wide = True
+
+    for url in urllist:
+      url = URL.Canonicalize(url)
+      output.Log('Index points to Sitemap file at: %s' % url, 2)
+      (scheme, netloc, path, query, frag) = urlparse.urlsplit(url)
+      file = os.path.basename(path)
+      file = urllib.unquote(file)
+      if wide:
+        file = encoder.WidenText(file)
+      if dir:
+        file = dir + os.sep + file
+      if file:
+        self._pathlist.append(file)
+        output.Log('Will attempt to read Sitemap file: %s' % file, 1)
+  #end def _MungeLocationListIntoFiles
+
+  def startElement(self, tag, attributes):
+    """SAX processing, called per node in the config stream.
+    As long as the new tag is legal in our current context, this
+    becomes an Open call on one context deeper.
+    """
+    # If this is the document node, we may have to look for a context stack
+    if (self._current < 0) and not self._contexts:
+      assert self._contexts_idx and self._contexts_stm
+      if tag == 'urlset':
+        self._contexts = self._contexts_stm
+      elif tag == 'sitemapindex':
+        self._contexts = self._contexts_idx
+        output.Log('File is a Sitemap index.', 2)
+      else:
+        output.Error('The document appears to be neither a Sitemap nor a '
+                     'Sitemap index.')
+        raise SchemaError
+
+    # Display a kinder error on a common mistake
+    if (self._current < 0) and (self._contexts == self._contexts_stm) and (
+      tag == 'sitemapindex'):
+      output.Error('A Sitemap index can not refer to another Sitemap index.')
+      raise SchemaError
+
+    # Verify no unexpected attributes
+    if attributes:
+      text = ''
+      for attr in attributes.keys():
+        # The document node will probably have namespaces
+        if self._current < 0:
+          if attr.find('xmlns') >= 0:
+            continue
+          if attr.find('xsi') >= 0:
+            continue
+        if text:
+          text = text + ', '
+        text = text + attr
+      if text:
+        output.Warn('Did not expect any attributes on any tag, instead tag '
+                     '"%s" had attributes: %s' % (tag, text))
+
+    # Switch contexts
+    if (self._current < 0) or (self._contexts[self._current].AcceptTag(tag)):
+      self._current = self._current + 1
+      assert self._current < len(self._contexts)
+      self._contexts[self._current].Open()
+    else:
+      output.Error('Can not accept tag "%s" where it appears.' % tag)
+      raise SchemaError
+  #end def startElement
+
+  def endElement(self, tag):
+    """SAX processing, called per node in the config stream.
+    This becomes a call to Close on one context followed by a call
+    to Return on the previous.
+    """
+    tag = tag  # Avoid warning on unused argument
+    assert self._current >= 0
+    retval = self._contexts[self._current].Close()
+    self._current = self._current - 1
+    if self._current >= 0:
+      self._contexts[self._current].Return(retval)
+    elif retval and (self._contexts == self._contexts_idx):
+      self._MungeLocationListIntoFiles(retval)
+  #end def endElement
+
+  def characters(self, text):
+    """SAX processing, called when text values are read.  Important to
+    note that one single text value may be split across multiple calls
+    of this method.
+    """
+    if (self._current < 0) or (
+      not self._contexts[self._current].AcceptText(text)):
+      if text.strip():
+        output.Error('Can not accept text "%s" where it appears.' % text)
+        raise SchemaError
+  #end def characters
+#end class InputSitemap
+
+
+class FilePathGenerator:
+  """
+  This class generates filenames in a series, upon request.
+  You can request any iteration number at any time, you don't
+  have to go in order.
+
+  Example of iterations for '/path/foo.xml.gz':
+    0           --> /path/foo.xml.gz
+    1           --> /path/foo1.xml.gz
+    2           --> /path/foo2.xml.gz
+    _index.xml  --> /path/foo_index.xml
+  """
+
+  def __init__(self):
+    self.is_gzip     = False                 # Is this a  GZIP file?
+
+    self._path       = None                  # '/path/'
+    self._prefix     = None                  # 'foo'
+    self._suffix     = None                  # '.xml.gz'
+  #end def __init__
+
+  def Preload(self, path):
+    """ Splits up a path into forms ready for recombination. """
+    path = encoder.MaybeNarrowPath(path)
+
+    # Get down to a base name
+    path = os.path.normpath(path)
+    base = os.path.basename(path).lower()
+    if not base:
+      output.Error('Couldn\'t parse the file path: %s' % path)
+      return False
+    lenbase = len(base)
+
+    # Recognize extension
+    lensuffix = 0
+    compare_suffix = ['.xml', '.xml.gz', '.gz']
+    for suffix in compare_suffix:
+      if base.endswith(suffix):
+        lensuffix = len(suffix)
+        break
+    if not lensuffix:
+      output.Error('The path "%s" doesn\'t end in a supported file '
+                   'extension.' % path)
+      return False
+    self.is_gzip = suffix.endswith('.gz')
+
+    # Split the original path
+    lenpath = len(path)
+    self._path   = path[:lenpath-lenbase]
+    self._prefix = path[lenpath-lenbase:lenpath-lensuffix]
+    self._suffix = path[lenpath-lensuffix:]
+
+    return True
+  #end def Preload
+
+  def GeneratePath(self, instance):
+    """ Generates the iterations, as described above. """
+    prefix = self._path + self._prefix
+    if type(instance) == types.IntType:
+      if instance:
+        return '%s%d%s' % (prefix, instance, self._suffix)
+      return prefix + self._suffix
+    return prefix + instance
+  #end def GeneratePath
+
+  def GenerateURL(self, instance, root_url):
+    """ Generates iterations, but as a URL instead of a path. """
+    prefix = root_url + self._prefix
+    retval = None
+    if type(instance) == types.IntType:
+      if instance:
+        retval = '%s%d%s' % (prefix, instance, self._suffix)
+      else:
+        retval = prefix + self._suffix
+    else:
+      retval = prefix + instance
+    return URL.Canonicalize(retval)
+  #end def GenerateURL
+
+  def GenerateWildURL(self, root_url):
+    """ Generates a wildcard that should match all our iterations """
+    prefix = URL.Canonicalize(root_url + self._prefix)
+    temp   = URL.Canonicalize(prefix + self._suffix)
+    suffix = temp[len(prefix):]
+    return prefix + '*' + suffix
+  #end def GenerateURL
+#end class FilePathGenerator
+
+
+class PerURLStatistics:
+  """ Keep track of some simple per-URL statistics, like file extension. """
+
+  def __init__(self):
+    self._extensions  = {}                  # Count of extension instances
+  #end def __init__
+
+  def Consume(self, url):
+    """ Log some stats for the URL.  At the moment, that means extension. """
+    if url and url.loc:
+      (scheme, netloc, path, query, frag) = urlparse.urlsplit(url.loc)
+      if not path:
+        return
+
+      # Recognize directories
+      if path.endswith('/'):
+        if self._extensions.has_key('/'):
+          self._extensions['/'] = self._extensions['/'] + 1
+        else:
+          self._extensions['/'] = 1
+        return
+
+      # Strip to a filename
+      i = path.rfind('/')
+      if i >= 0:
+        assert i < len(path)
+        path = path[i:]
+
+      # Find extension
+      i = path.rfind('.')
+      if i > 0:
+        assert i < len(path)
+        ext = path[i:].lower()
+        if self._extensions.has_key(ext):
+          self._extensions[ext] = self._extensions[ext] + 1
+        else:
+          self._extensions[ext] = 1
+      else:
+        if self._extensions.has_key('(no extension)'):
+          self._extensions['(no extension)'] = self._extensions[
+            '(no extension)'] + 1
+        else:
+          self._extensions['(no extension)'] = 1
+  #end def Consume
+
+  def Log(self):
+    """ Dump out stats to the output. """
+    if len(self._extensions):
+      output.Log('Count of file extensions on URLs:', 1)
+      set = self._extensions.keys()
+      set.sort()
+      for ext in set:
+        output.Log(' %7d  %s' % (self._extensions[ext], ext), 1)
+  #end def Log
+
+class Sitemap(xml.sax.handler.ContentHandler):
+  """
+  This is the big workhorse class that processes your inputs and spits
+  out sitemap files.  It is built as a SAX handler for set up purposes.
+  That is, it processes an XML stream to bring itself up.
+  """
+
+  def __init__(self, suppress_notify):
+    xml.sax.handler.ContentHandler.__init__(self)
+    self._filters      = []                  # Filter objects
+    self._inputs       = []                  # Input objects
+    self._urls         = {}                  # Maps URLs to count of dups
+    self._set          = []                  # Current set of URLs
+    self._filegen      = None                # Path generator for output files
+    self._wildurl1     = None                # Sitemap URLs to filter out
+    self._wildurl2     = None                # Sitemap URLs to filter out
+    self._sitemaps     = 0                   # Number of output files
+    # We init _dup_max to 2 so the default priority is 0.5 instead of 1.0
+    self._dup_max      = 2                   # Max number of duplicate URLs
+    self._stat         = PerURLStatistics()  # Some simple stats
+    self._in_site      = False               # SAX: are we in a Site node?
+    self._in_Site_ever = False               # SAX: were we ever in a Site?
+
+    self._default_enc  = None                # Best encoding to try on URLs
+    self._base_url     = None                # Prefix to all valid URLs
+    self._store_into   = None                # Output filepath
+    self._suppress     = suppress_notify     # Suppress notify of servers
+  #end def __init__
+
+  def ValidateBasicConfig(self):
+    """ Verifies (and cleans up) the basic user-configurable options. """
+    all_good = True
+
+    if self._default_enc:
+      encoder.SetUserEncoding(self._default_enc)
+
+    # Canonicalize the base_url
+    if all_good and not self._base_url:
+      output.Error('A site needs a "base_url" attribute.')
+      all_good = False
+    if all_good and not URL.IsAbsolute(self._base_url):
+        output.Error('The "base_url" must be absolute, not relative: %s' %
+                     self._base_url)
+        all_good = False
+    if all_good:
+      self._base_url = URL.Canonicalize(self._base_url)
+      if not self._base_url.endswith('/'):
+        self._base_url = self._base_url + '/'
+      output.Log('BaseURL is set to: %s' % self._base_url, 2)
+
+    # Load store_into into a generator
+    if all_good:
+      if self._store_into:
+        self._filegen = FilePathGenerator()
+        if not self._filegen.Preload(self._store_into):
+          all_good = False
+      else:
+        output.Error('A site needs a "store_into" attribute.')
+        all_good = False
+
+    # Ask the generator for patterns on what its output will look like
+    if all_good:
+      self._wildurl1 = self._filegen.GenerateWildURL(self._base_url)
+      self._wildurl2 = self._filegen.GenerateURL(SITEINDEX_SUFFIX,
+                                                 self._base_url)
+
+    # Unify various forms of False
+    if all_good:
+      if self._suppress:
+        if (type(self._suppress) == types.StringType) or (type(self._suppress)
+                                 == types.UnicodeType):
+          if (self._suppress == '0') or (self._suppress.lower() == 'false'):
+            self._suppress = False
+
+    # Done
+    if not all_good:
+      output.Log('See "example_config.xml" for more information.', 0)
+    return all_good
+  #end def ValidateBasicConfig
+
+  def Generate(self):
+    """ Run over all the Inputs and ask them to Produce """
+    # Run the inputs
+    for input in self._inputs:
+      input.ProduceURLs(self.ConsumeURL)
+
+    # Do last flushes
+    if len(self._set):
+      self.FlushSet()
+    if not self._sitemaps:
+      output.Warn('No URLs were recorded, writing an empty sitemap.')
+      self.FlushSet()
+
+    # Write an index as needed
+    if self._sitemaps > 1:
+      self.WriteIndex()
+
+    # Notify
+    self.NotifySearch()
+
+    # Dump stats
+    self._stat.Log()
+  #end def Generate
+
+  def ConsumeURL(self, url, allow_fragment):
+    """
+    All per-URL processing comes together here, regardless of Input.
+    Here we run filters, remove duplicates, spill to disk as needed, etc.
+    """
+    if not url:
+      return
+
+    # Validate
+    if not url.Validate(self._base_url, allow_fragment):
+      return
+
+    # Run filters
+    accept = None
+    for filter in self._filters:
+      accept = filter.Apply(url)
+      if accept != None:
+        break
+    if not (accept or (accept == None)):
+      url.Log(prefix='FILTERED', level=2)
+      return
+
+    # Ignore our out output URLs
+    if fnmatch.fnmatchcase(url.loc, self._wildurl1) or fnmatch.fnmatchcase(
+      url.loc, self._wildurl2):
+      url.Log(prefix='IGNORED (output file)', level=2)
+      return
+
+    # Note the sighting
+    hash = url.MakeHash()
+    if self._urls.has_key(hash):
+      dup = self._urls[hash]
+      if dup > 0:
+        dup = dup + 1
+        self._urls[hash] = dup
+        if self._dup_max < dup:
+          self._dup_max = dup
+      url.Log(prefix='DUPLICATE')
+      return
+
+    # Acceptance -- add to set
+    self._urls[hash] = 1
+    self._set.append(url)
+    self._stat.Consume(url)
+    url.Log()
+
+    # Flush the set if needed
+    if len(self._set) >= MAXURLS_PER_SITEMAP:
+      self.FlushSet()
+  #end def ConsumeURL
+
+  def FlushSet(self):
+    """
+    Flush the current set of URLs to the output.  This is a little
+    slow because we like to sort them all and normalize the priorities
+    before dumping.
+    """
+
+    # Sort and normalize
+    output.Log('Sorting and normalizing collected URLs.', 1)
+    self._set.sort()
+    for url in self._set:
+      hash = url.MakeHash()
+      dup = self._urls[hash]
+      if dup > 0:
+        self._urls[hash] = -1
+        if not url.priority:
+          url.priority = '%.4f' % (float(dup) / float(self._dup_max))
+
+    # Get the filename we're going to write to
+    filename = self._filegen.GeneratePath(self._sitemaps)
+    if not filename:
+      output.Fatal('Unexpected: Couldn\'t generate output filename.')
+    self._sitemaps = self._sitemaps + 1
+    output.Log('Writing Sitemap file "%s" with %d URLs' %
+        (filename, len(self._set)), 1)
+
+    # Write to it
+    frame = None
+    file  = None
+
+    try:
+      if self._filegen.is_gzip:
+        basename = os.path.basename(filename);
+        frame = open(filename, 'wb')
+        file = gzip.GzipFile(fileobj=frame, filename=basename, mode='wt')
+      else:
+        file = open(filename, 'wt')
+
+      file.write(SITEMAP_HEADER)
+      for url in self._set:
+        url.WriteXML(file)
+      file.write(SITEMAP_FOOTER)
+
+      file.close()
+      if frame:
+        frame.close()
+
+      frame = None
+      file  = None
+    except IOError:
+      output.Fatal('Couldn\'t write out to file: %s' % filename)
+    os.chmod(filename, 0644)
+
+    # Flush
+    self._set = []
+  #end def FlushSet
+
+  def WriteIndex(self):
+    """ Write the master index of all Sitemap files """
+    # Make a filename
+    filename = self._filegen.GeneratePath(SITEINDEX_SUFFIX)
+    if not filename:
+      output.Fatal('Unexpected: Couldn\'t generate output index filename.')
+    output.Log('Writing index file "%s" with %d Sitemaps' %
+        (filename, self._sitemaps), 1)
+
+    # Make a lastmod time
+    lastmod = TimestampISO8601(time.time())
+
+    # Write to it
+    try:
+      fd = open(filename, 'wt')
+      fd.write(SITEINDEX_HEADER)
+
+      for mapnumber in range(0,self._sitemaps):
+        # Write the entry
+        mapurl = self._filegen.GenerateURL(mapnumber, self._base_url)
+        mapattributes = { 'loc' : mapurl, 'lastmod' : lastmod }
+        fd.write(SITEINDEX_ENTRY % mapattributes)
+
+      fd.write(SITEINDEX_FOOTER)
+
+      fd.close()
+      fd = None
+    except IOError:
+      output.Fatal('Couldn\'t write out to file: %s' % filename)
+    os.chmod(filename, 0644)
+  #end def WriteIndex
+
+  def NotifySearch(self):
+    """ Send notification of the new Sitemap(s) to the search engines. """
+    if self._suppress:
+      output.Log('Search engine notification is suppressed.', 1)
+      return
+
+    output.Log('Notifying search engines.', 1)
+
+    # Override the urllib's opener class with one that doesn't ignore 404s
+    class ExceptionURLopener(urllib.FancyURLopener):
+      def http_error_default(self, url, fp, errcode, errmsg, headers):
+        output.Log('HTTP error %d: %s' % (errcode, errmsg), 2)
+        raise IOError
+      #end def http_error_default
+    #end class ExceptionURLOpener
+    old_opener = urllib._urlopener
+    urllib._urlopener = ExceptionURLopener()
+
+    # Build the URL we want to send in
+    if self._sitemaps > 1:
+      url = self._filegen.GenerateURL(SITEINDEX_SUFFIX, self._base_url)
+    else:
+      url = self._filegen.GenerateURL(0, self._base_url)
+
+    # Test if we can hit it ourselves
+    try:
+      u = urllib.urlopen(url)
+      u.close()
+    except IOError:
+      output.Error('When attempting to access our generated Sitemap at the '
+                   'following URL:\n    %s\n  we failed to read it.  Please '
+                   'verify the store_into path you specified in\n'
+                   '  your configuration file is web-accessable.  Consult '
+                   'the FAQ for more\n  information.' % url)
+      output.Warn('Proceeding to notify with an unverifyable URL.')
+
+    # Cycle through notifications
+    # To understand this, see the comment near the NOTIFICATION_SITES comment
+    for ping in NOTIFICATION_SITES:
+      query_map             = ping[3]
+      query_attr            = ping[5]
+      query_map[query_attr] = url
+      query = urllib.urlencode(query_map)
+      notify = urlparse.urlunsplit((ping[0], ping[1], ping[2], query, ping[4]))
+
+      # Send the notification
+      output.Log('Notifying: %s' % ping[1], 1)
+      output.Log('Notification URL: %s' % notify, 2)
+      try:
+        u = urllib.urlopen(notify)
+        u.read()
+        u.close()
+      except IOError:
+        output.Warn('Cannot contact: %s' % ping[1])
+
+    if old_opener:
+      urllib._urlopener = old_opener
+  #end def NotifySearch
+
+  def startElement(self, tag, attributes):
+    """ SAX processing, called per node in the config stream. """
+
+    if tag == 'site':
+      if self._in_site:
+        output.Error('Can not nest Site entries in the configuration.')
+      else:
+        self._in_site     = True
+
+        if not ValidateAttributes('SITE', attributes,
+          ('verbose', 'default_encoding', 'base_url', 'store_into',
+           'suppress_search_engine_notify')):
+          return
+
+        verbose           = attributes.get('verbose', 0)
+        if verbose:
+          output.SetVerbose(verbose)
+
+        self._default_enc = attributes.get('default_encoding')
+        self._base_url    = attributes.get('base_url')
+        self._store_into  = attributes.get('store_into')
+        if not self._suppress:
+          self._suppress  = attributes.get('suppress_search_engine_notify',
+                                            False)
+        self.ValidateBasicConfig()
+
+    elif tag == 'filter':
+      self._filters.append(Filter(attributes))
+
+    elif tag == 'url':
+      self._inputs.append(InputURL(attributes))
+
+    elif tag == 'urllist':
+      for attributeset in ExpandPathAttribute(attributes, 'path'):
+        self._inputs.append(InputURLList(attributeset))
+
+    elif tag == 'directory':
+      self._inputs.append(InputDirectory(attributes, self._base_url))
+
+    elif tag == 'accesslog':
+      for attributeset in ExpandPathAttribute(attributes, 'path'):
+        self._inputs.append(InputAccessLog(attributeset))
+
+    elif tag == 'sitemap':
+      for attributeset in ExpandPathAttribute(attributes, 'path'):
+        self._inputs.append(InputSitemap(attributeset))
+
+    else:
+      output.Error('Unrecognized tag in the configuration: %s' % tag)
+  #end def startElement
+
+  def endElement(self, tag):
+    """ SAX processing, called per node in the config stream. """
+    if tag == 'site':
+      assert self._in_site
+      self._in_site      = False
+      self._in_site_ever = True
+  #end def endElement
+
+  def endDocument(self):
+    """ End of SAX, verify we can proceed. """
+    if not self._in_site_ever:
+      output.Error('The configuration must specify a "site" element.')
+    else:
+      if not self._inputs:
+        output.Warn('There were no inputs to generate a sitemap from.')
+  #end def endDocument
+#end class Sitemap
+
+
+def ValidateAttributes(tag, attributes, goodattributes):
+  """ Makes sure 'attributes' does not contain any attribute not
+      listed in 'goodattributes' """
+  all_good = True
+  for attr in attributes.keys():
+    if not attr in goodattributes:
+      output.Error('Unknown %s attribute: %s' % (tag, attr))
+      all_good = False
+  return all_good
+#end def ValidateAttributes
+
+def ExpandPathAttribute(src, attrib):
+  """ Given a dictionary of attributes, return a list of dictionaries
+      with all the same attributes except for the one named attrib.
+      That one, we treat as a file path and expand into all its possible
+      variations. """
+  # Do the path expansion.  On any error, just return the source dictionary.
+  path = src.get(attrib)
+  if not path:
+    return [src]
+  path = encoder.MaybeNarrowPath(path);
+  pathlist = glob.glob(path)
+  if not pathlist:
+    return [src]
+
+  # If this isn't actually a dictionary, make it one
+  if type(src) != types.DictionaryType:
+    tmp = {}
+    for key in src.keys():
+      tmp[key] = src[key]
+    src = tmp
+
+  # Create N new dictionaries
+  retval = []
+  for path in pathlist:
+    dst = src.copy()
+    dst[attrib] = path
+    retval.append(dst)
+
+  return retval
+#end def ExpandPathAttribute
+
+def OpenFileForRead(path, logtext):
+  """ Opens a text file, be it GZip or plain """
+
+  frame = None
+  file  = None
+
+  if not path:
+    return (frame, file)
+
+  try:
+    if path.endswith('.gz'):
+      frame = open(path, 'rb')
+      file = gzip.GzipFile(fileobj=frame, mode='rt')
+    else:
+      file = open(path, 'rt')
+
+    if logtext:
+      output.Log('Opened %s file: %s' % (logtext, path), 1)
+    else:
+      output.Log('Opened file: %s' % path, 1)
+  except IOError:
+    output.Error('Can not open file: %s' % path)
+
+  return (frame, file)
+#end def OpenFileForRead
+
+def TimestampISO8601(t):
+  """Seconds since epoch (1970-01-01) --> ISO 8601 time string."""
+  return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(t))
+#end def TimestampISO8601
+
+def CreateSitemapFromFile(configpath, suppress_notify):
+  """ Sets up a new Sitemap object from the specified configuration file.  """
+
+  # Remember error count on the way in
+  num_errors = output.num_errors
+
+  # Rev up SAX to parse the config
+  sitemap = Sitemap(suppress_notify)
+  try:
+    output.Log('Reading configuration file: %s' % configpath, 0)
+    xml.sax.parse(configpath, sitemap)
+  except IOError:
+    output.Error('Cannot read configuration file: %s' % configpath)
+  except xml.sax._exceptions.SAXParseException, e:
+    output.Error('XML error in the config file (line %d, column %d): %s' %
+                 (e._linenum, e._colnum, e.getMessage()))
+  except xml.sax._exceptions.SAXReaderNotAvailable:
+    output.Error('Some installs of Python 2.2 did not include complete support'
+                 ' for XML.\n  Please try upgrading your version of Python'
+                 ' and re-running the script.')
+
+  # If we added any errors, return no sitemap
+  if num_errors == output.num_errors:
+    return sitemap
+  return None
+#end def CreateSitemapFromFile
+
+def ProcessCommandFlags(args):
+  """
+  Parse command line flags per specified usage, pick off key, value pairs
+  All flags of type "--key=value" will be processed as __flags[key] = value,
+                    "--option" will be processed as __flags[option] = option
+  """
+
+  flags   = {}
+  rkeyval = '--(?P<key>\S*)[=](?P<value>\S*)' # --key=val
+  roption = '--(?P<option>\S*)'               # --key
+  r = '(' + rkeyval + ')|(' + roption + ')'
+  rc = re.compile(r)
+  for a in args:
+    try:
+      rcg = rc.search(a).groupdict()
+      if rcg.has_key('key'):
+        flags[rcg['key']] = rcg['value']
+      if rcg.has_key('option'):
+        flags[rcg['option']] = rcg['option']
+    except AttributeError:
+      return None
+  return flags
+#end def ProcessCommandFlags
+
+
+#
+# __main__
+#
+
+if __name__ == '__main__':
+  flags = ProcessCommandFlags(sys.argv[1:])
+  if not flags or not flags.has_key('config') or flags.has_key('help'):
+    output.Log(__usage__, 0)
+  else:
+    suppress_notify = flags.has_key('testing')
+    sitemap = CreateSitemapFromFile(flags['config'], suppress_notify)
+    if not sitemap:
+      output.Log('Configuration file errors -- exiting.', 0)
+    else:
+      sitemap.Generate()
+      output.Log('Number of errors: %d' % output.num_errors, 1)
+      output.Log('Number of warnings: %d' % output.num_warns, 1)

+ 211 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2010-news.rst

@@ -0,0 +1,211 @@
+Changelog - 2010
+================
+
+0.12.0 / 2010-12-22
+-------------------
+
+- Add support for logging configuration using a ini file.
+  It uses the standard Python logging's module Configuration
+  file format and allows anyone to use his custom file handler
+- Add IPV6 support
+- Add multidomain application example
+- Improve gunicorn_django command when importing settings module
+  using DJANGO_SETTINGS_MODULE environment variable
+- Send appropriate error status on http parsing
+- Fix pidfile, set permissions so other user can read
+  it and use it.
+- Fix temporary file leaking
+- Fix setpgrp issue, can now be launched via ubuntu upstart
+- Set the number of workers to zero on WINCH
+
+0.11.2 / 2010-10-30
+-------------------
+
+* Add SERVER_SOFTWARE to the os.environ
+* Add support for django settings environment variable
+* Add support for logging configuration in Paster ini-files
+* Improve arbiter notification in asynchronous workers
+* Display the right error when a worker can't be used
+* Fix Django support
+* Fix HUP with Paster applications
+* Fix readline in wsgi.input
+
+0.11.1 / 2010-09-02
+-------------------
+
+* Implement max-requests feature to prevent memory leaks.
+* Added 'worker_exit' server hook.
+* Reseed the random number generator after fork().
+* Improve Eventlet worker.
+* Fix Django command `run_gunicorn`.
+* Fix the default proc name internal setting.
+* Workaround to prevent Gevent worker to segfault on MacOSX.
+
+0.11.0 / 2010-08-12
+-------------------
+
+* Improve dramatically performances of Gevent and Eventlet workers
+* Optimize HTTP parsing
+* Drop Server and Date headers in start_response when provided.
+* Fix latency issue in async workers
+
+0.10.1 / 2010-08-06
+-------------------
+
+* Improve gevent's workers. Add "egg:gunicorn#gevent_wsgi" worker using
+  `gevent.wsgi <http://www.gevent.org/gevent.wsgi.html>`_ and
+  "egg:gunicorn#gevent_pywsgi" worker using `gevent.pywsgi
+  <http://www.gevent.org/gevent.pywsgi.html>`_ .
+  **"egg:gunicorn#gevent"** using our own HTTP parser is still here and
+  is **recommended** for normal uses. Use the "gevent.wsgi" parser if you
+  need really fast connections and don't need streaming, keepalive or ssl.
+* Add pre/post request hooks
+* Exit more quietly
+* Fix gevent dns issue
+
+0.10.0 / 2010-07-08
+-------------------
+
+* New HTTP parser.
+* New HUP behaviour. Re-reads the configuration and then reloads all
+  worker processes without changing the master process id. Helpful for
+  code reloading and monitoring applications like supervisord and runit.
+* Added a preload configuration parameter. By default, application code
+  is now loaded after a worker forks. This couple with the new HUP
+  handling can be used for dev servers to do hot code reloading. Using
+  the preload flag can help a bit in small memory VM's.
+* Allow people to pass command line arguments to WSGI applications. See:
+  `examples/alt_spec.py
+  <http://github.com/benoitc/gunicorn/raw/master/examples/alt_spec.py>`_
+* Added an example gevent reloader configuration:
+  `examples/example_gevent_reloader.py
+  <http://github.com/benoitc/gunicorn/blob/master/examples/example_gevent_reloader.py>`_.
+* New gevent worker "egg:gunicorn#gevent2", working with gevent.wsgi.
+* Internal refactoring and various bug fixes.
+* New documentation website.
+
+0.9.1 / 2010-05-26
+------------------
+
+* Support https via X-Forwarded-Protocol or X-Forwarded-Ssl headers
+* Fix configuration
+* Remove -d options which was used instead of -D for daemon.
+* Fix umask in unix socket
+
+0.9.0 / 2010-05-24
+------------------
+
+* Added *when_ready* hook. Called just after the server is started
+* Added *preload* setting. Load application code before the worker processes
+  are forked.
+* Refactored Config
+* Fix pidfile
+* Fix QUIT/HUP in async workers
+* Fix reexec
+* Documentation improvements
+
+0.8.1 / 2010-04-29
+------------------
+
+* Fix builtins import in config
+* Fix installation with pip
+* Fix Tornado WSGI support
+* Delay application loading until after processing all configuration
+
+0.8.0 / 2010-04-22
+------------------
+
+* Refactored Worker management for better async support. Now use the -k option
+  to set the type of request processing to use
+* Added support for Tornado_
+
+0.7.2 / 2010-04-15
+------------------
+
+* Added --spew option to help debugging (installs a system trace hook)
+* Some fixes in async arbiters
+* Fix a bug in start_response on error
+
+0.7.1 / 2010-04-01
+------------------
+
+* Fix bug when responses have no body.
+
+0.7.0 / 2010-03-26
+------------------
+
+* Added support for Eventlet_ and Gevent_ based workers.
+* Added Websockets_ support
+* Fix Chunked Encoding
+* Fix SIGWINCH on OpenBSD_
+* Fix `PEP 333`_ compliance for the write callable.
+
+0.6.5 / 2010-03-11
+------------------
+
+* Fix pidfile handling
+* Fix Exception Error
+
+0.6.4 / 2010-03-08
+------------------
+
+* Use cStringIO for performance when possible.
+* Fix worker freeze when a remote connection closes unexpectedly.
+
+0.6.3 / 2010-03-07
+------------------
+
+* Make HTTP parsing faster.
+* Various bug fixes
+
+0.6.2 / 2010-03-01
+------------------
+
+* Added support for chunked response.
+* Added proc_name option to the config file.
+* Improved the HTTP parser. It now uses buffers instead of strings to store
+  temporary data.
+* Improved performance when sending responses.
+* Workers are now murdered by age (the oldest is killed first).
+
+0.6.1 / 2010-02-24
+------------------
+
+* Added gunicorn config file support for Django admin command
+* Fix gunicorn config file. -c was broken.
+* Removed TTIN/TTOU from workers which blocked other signals.
+
+0.6.0 / 2010-02-22
+------------------
+
+* Added setproctitle support
+* Change privilege switch behavior. We now work like NGINX, master keeps the
+  permissions, new uid/gid permissions are only set for workers.
+
+0.5.1 / 2010-02-22
+------------------
+
+* Fix umask
+* Added Debian packaging
+
+0.5.0 / 2010-02-20
+------------------
+
+* Added `configuration file <configuration.html>`_ handler.
+* Added support for pre/post fork hooks
+* Added support for before_exec hook
+* Added support for unix sockets
+* Added launch of workers processes under different user/group
+* Added umask option
+* Added SCRIPT_NAME support
+* Better support of some exotic settings for Django projects
+* Better support of Paste-compatible applications
+* Some refactoring to make the code easier to hack
+* Allow multiple keys in request and response headers
+
+.. _Tornado: http://www.tornadoweb.org/
+.. _`PEP 333`: https://www.python.org/dev/peps/pep-0333/
+.. _Eventlet: http://eventlet.net/
+.. _Gevent: http://www.gevent.org/
+.. _OpenBSD: https://www.openbsd.org/
+.. _Websockets: https://html.spec.whatwg.org/multipage/web-sockets.html

+ 73 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2011-news.rst

@@ -0,0 +1,73 @@
+Changelog - 2011
+================
+
+0.13.4 / 2011-09-23
+-------------------
+
+- fix util.closerange function used to prevent leaking fds on python 2.5
+  (typo)
+
+0.13.3 / 2011-09-19
+-------------------
+- refactor gevent worker
+- prevent leaking fds on reexec
+- fix inverted request_time computation
+
+0.13.2 / 2011-09-17
+-------------------
+
+- Add support for Tornado 2.0 in tornado worker
+- Improve access logs: allows customisation of the log format & add
+  request time
+- Logger module is now pluggable
+- Improve graceful shutdown in Python versions >= 2.6
+- Fix post_request root arity for compatibility
+- Fix sendfile support
+- Fix Django reloading
+
+0.13.1 / 2011-08-22
+-------------------
+
+- Fix unix socket. log argument was missing.
+
+0.13.0 / 2011-08-22
+-------------------
+
+- Improve logging: allows file-reopening and add access log file
+  compatible with the `apache combined log format <http://httpd.apache.org/docs/2.0/logs.html#combined>`_
+- Add the possibility to set custom SSL headers. X-Forwarded-Protocol
+  and X-Forwarded-SSL are still the default
+- New `on_reload` hook to customize how gunicorn spawn new workers on
+  SIGHUP
+- Handle projects with relative path in django_gunicorn command
+- Preserve path parameters in PATH_INFO
+- post_request hook now accepts the environ as argument.
+- When stopping the arbiter, close the listener asap.
+- Fix Django command `run_gunicorn` in settings reloading
+- Fix Tornado_ worker exiting
+- Fix the use of sendfile in wsgi.file_wrapper
+
+
+0.12.2 / 2011-05-18
+-------------------
+
+- Add wsgi.file_wrapper optimised for FreeBSD, Linux & MacOSX (use
+  sendfile if available)
+- Fix django run_gunicorn command. Make sure we reload the application
+  code.
+- Fix django localisation
+- Compatible with gevent 0.14dev
+
+0.12.1 / 2011-03-23
+-------------------
+
+- Add "on_starting" hook. This hook can be used to set anything before
+  the arbiter really start
+- Support bdist_rpm in setup
+- Improve content-length handling (pep 3333)
+- Improve Django support
+- Fix daemonizing (#142)
+- Fix ipv6 handling
+
+
+.. _Tornado: http://www.tornadoweb.org/

+ 128 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2012-news.rst

@@ -0,0 +1,128 @@
+Changelog - 2012
+================
+
+0.17.0 / 2012-12-25
+-------------------
+
+- allows gunicorn to bind to multiple address
+- add SSL support
+- add syslog support
+- add nworkers_changed hook
+- add response arg for post_request hook
+- parse command line with argparse (replace deprecated optparse)
+- fix PWD detection in arbiter
+- miscellaneous PEP8 fixes
+
+0.16.1 / 2012-11-19
+-------------------
+
+- Fix packaging
+
+0.16.0 / 2012-11-19
+-------------------
+
+- **Added support for Python 3.2 & 3.3**
+- Expose --pythonpath command to all gunicorn commands
+- Honor $PORT environment variable, useful for deployment on heroku
+- Removed support for Python 2.5
+- Make sure we reopen the logs on the console
+- Fix django settings module detection from path
+- Reverted timeout for client socket. Fix issue on blocking issues.
+- Fixed gevent worker
+
+0.15.0 / 2012-10-18
+-------------------
+
+- new documentation site on http://docs.gunicorn.org
+- new website on http://gunicorn.org
+- add `haproxy PROXY protocol <http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt>`_ support
+- add  ForwardedAllowIPS option: allows to filter Front-end's IPs
+  allowed to handle X-Forwarded-* headers.
+- add callable hooks for paster config
+- add x-forwarded-proto as secure scheme default (Heroku is using this)
+- allows gunicorn to load a pre-compiled application
+- support file reopening & reexec for all loggers
+- initialize the logging config file with defaults.
+- set timeout for client socket (slow client DoS).
+- NoMoreData, ChunkMissingTerminator, InvalidChunkSize are now
+  IOError exceptions
+- fix graceful shutdown in gevent
+- fix limit request line check
+
+0.14.6 / 2012-07-26
+-------------------
+
+
+- fix gevent & subproces
+- fix request line length check
+- fix keepalive = 0
+- fix tornado worker
+
+0.14.5 / 2012-06-24
+--------------------
+
+- fix logging during daemonisation
+
+0.14.4 / 2012-06-24
+-------------------
+
+- new --graceful-timeout option
+- fix multiple issues with request limit
+- more fixes in django settings resolutions
+- fix gevent.core import
+- fix keepalive=0 in eventlet worker
+- fix handle_error display with the unix worker
+- fix tornado.wsgi.WSGIApplication calling error
+
+- **breaking change**: take the control on graceful reload back.
+  graceful can't be overrided anymore using the on_reload function.
+
+0.14.3 / 2012-05-15
+-------------------
+
+- improvement: performance of http.body.Body.readline()
+- improvement: log HTTP errors in access log like Apache
+- improvement: display traceback when the worker fails to boot
+- improvement: makes gunicorn work with gevent 1.0
+- examples: websocket example now supports hybi13
+- fix: reopen log files after initialization
+- fix: websockets support
+- fix: django1.4 support
+- fix: only load the paster application 1 time
+
+0.14.2 / 2012-03-16
+-------------------
+
+- add validate_class validator: allows to use a class or a method to
+  initialize the app during in-code configuration
+- add support for max_requests in tornado worker
+- add support for disabling x_forwarded_for_header in tornado worker
+- gevent_wsgi is now an alias of gevent_pywsgi
+- Fix gevent_pywsgi worker
+
+0.14.1 / 2012-03-02
+-------------------
+
+- fixing source archive, reducing its size
+
+0.14.0 / 2012-02-27
+-------------------
+
+- check if Request line is too large: You can now pass the parameter
+  ``--limit-request-line`` or set the ``limit_request_line`` in your
+  configuration file to set the max size of the request line in bytes.
+- limit the number of headers fields and their size. Add
+  ``--limit-request-field`` and ``limit-request-field-size`` settings
+- add ``p`` variable to the log access format to log pidfile
+- add ``{HeaderName}o`` variable to the logo access format to log the
+  response header HeaderName
+- request header is now logged with the variable ``{HeaderName}i`` in the
+  access log file
+- improve error logging
+- support logging.configFile
+- support django 1.4 in both gunicorn_django & run_gunicorn command
+- improve reload in django run_gunicorn command (should just work now)
+- allows people to set the ``X-Forwarded-For`` header key and disable it by
+  setting an empty string.
+- fix support of Tornado
+- many other fixes.

+ 90 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2013-news.rst

@@ -0,0 +1,90 @@
+Changelog - 2013
+================
+
+18.0 / 2013-08-26
+-----------------
+
+- new: add ``-e/--env`` command line argument to pass an environment variables to
+  gunicorn
+- new: add ``--chdir`` command line argument to specified directory
+  before apps loading.  - new: add wsgi.file_wrapper support in async workers
+- new: add ``--paste`` command line argument to set the paster config file
+- deprecated: the command ``gunicorn_django`` is now deprecated. You should now
+  run your application with the WSGI interface installed with your project (see
+  https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/gunicorn/) for
+  more infos.
+- deprecated:  the command ``gunicorn_paste`` is deprecated. You now should use
+  the new ``--paste`` argument to set the configuration file of your paster
+  application.
+- fix: Removes unmatched leading quote from the beginning of the default access
+  log format string
+- fix: null timeout
+- fix: gevent worker
+- fix: don't reload the paster app when using pserve
+- fix: after closing for error do not keep alive the connection
+- fix: responses 1xx, 204 and 304 should not force the connection to be closed
+
+17.5 / 2013-07-03
+------------------
+
+- new: add signals documentation
+- new: add post_worker_init hook for workers
+- new: try to use gunicorn.conf.py in current folder as the default
+  config file.
+- fix graceful timeout with the Eventlet worker
+- fix: don't raise an error when closing the socket if already closed
+- fix: fix --settings parameter for django application and try to find
+  the django settings when using the ``gunicorn`` command.
+- fix: give the initial global_conf to paster application
+- fix: fix 'Expect: 100-continue' support on Python 3
+
+New versionning:
+++++++++++++++++
+
+With this release, the versionning of Gunicorn is changing. Gunicorn is
+stable since a long time and there is no point to release a "1.0" now.
+It should have been done since a long time. 0.17 really meant it was the
+17th stable version. From the beginning we have only 2 kind of
+releases:
+
+major release: releases with major changes or huge features added
+services releases: fixes and minor features added So from now we will
+apply the following versionning ``<major>.<service>``. For example ``17.5`` is a
+service release.
+
+0.17.4 / 2013-04-24
+-------------------
+
+- fix unix socket address parsing
+
+0.17.3 / 2013-04-23
+-------------------
+
+- add systemd sockets support
+- add ``python -m gunicorn.app.wsgiapp`` support
+- improve logger class inheritance
+- exit when the config file isn't found
+- add the -R option to enable stdio inheritance in daemon mode
+- don't close file descriptors > 3 in daemon mode
+- improve STDOUT/STDERR logging
+- fix pythonpath option
+- fix pidfile creation on Python 3
+- fix gevent worker exit
+- fix ipv6 detection when the platform isn't supporting it
+
+0.17.2 / 2013-01-07
+-------------------
+
+- optimize readline
+- make imports errors more visible when loading an app or a logging
+  class
+- fix tornado worker: don't pass ssl options if there are none
+- fix PEP3333: accept only bytetrings in the response body
+- fix support on CYGWIN platforms
+
+0.17.1 / 2013-01-05
+-------------------
+
+- add syslog facility name setting
+- fix ``--version`` command line argument
+- fix wsgi url_scheme for https

+ 228 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2014-news.rst

@@ -0,0 +1,228 @@
+================
+Changelog - 2014
+================
+
+.. note::
+
+   Please see :doc:`news` for the latest changes.
+
+19.1.1 / 2014-08-16
+===================
+
+Changes
+-------
+
+Core
+++++
+
+- fix :issue:`835`: display correct pid of already running instance
+- fix :pr:`833`: fix `PyTest` class in setup.py.
+
+
+Logging
++++++++
+
+- fix :issue:`838`: statsd logger, send statsd timing metrics in milliseconds
+- fix :issue:`839`: statsd logger, allows for empty log message while pushing
+  metrics and restore worker number in DEBUG logs
+- fix :issue:`850`: add timezone to logging
+- fix :issue:`853`: Respect logger_class setting unless statsd is on
+
+AioHttp worker
+++++++++++++++
+
+- fix :issue:`830` make sure gaiohttp worker is shipped with gunicorn.
+
+19.1 / 2014-07-26
+=================
+
+Changes
+-------
+
+Core
+++++
+
+- fix :issue:`785`: handle binary type address given to a client socket address
+- fix graceful shutdown. make sure QUIT and TERMS signals are switched everywhere.
+- :issue:`799`: fix support loading config from module
+- :issue:`805`: fix check for file-like objects
+- fix :issue:`815`: args validation in WSGIApplication.init
+- fix :issue:`787`: check if we load a pyc file or not.
+
+
+Tornado worker
+++++++++++++++
+
+- fix :issue:`771`: support tornado 4.0
+- fix :issue:`783`: x_headers error. The x-forwarded-headers option has been removed
+  in `c4873681299212d6082cd9902740eef18c2f14f1
+  <https://github.com/benoitc/gunicorn/commit/c4873681299212d6082cd9902740eef18c2f14f1>`_.
+  The discussion is available on :pr:`633`.
+
+
+AioHttp worker
+++++++++++++++
+
+- fix: fetch all body in input. fix :issue:`803`
+- fix: don't install the worker if python < 3.3
+- fix :issue:`822`: Support UNIX sockets in gaiohttp worker
+
+
+Async worker
+++++++++++++
+
+- fix :issue:`790`: StopIteration shouldn't be catched at this level.
+
+
+Logging
++++++++
+
+- add statsd logging handler fix :issue:`748`
+
+
+Paster
+++++++
+
+- fix :issue:`809`: Set global logging configuration from a Paste config.
+
+
+Extra
++++++
+
+- fix RuntimeError in gunicorn.reloader (:issue:`807`)
+
+
+Documentation
++++++++++++++
+
+- update faq: put a note on how `watch logs in the console
+  <http://docs.gunicorn.org/en/latest/faq.html#why-i-don-t-see-any-logs-in-the-console>`_
+  since many people asked for it.
+
+
+19.0 / 2014-06-12
+=================
+
+Gunicorn 19.0 is a major release with new features and fixes. This
+version improve a lot the usage of Gunicorn with python 3 by adding `two
+new workers <http://docs.gunicorn.org/en/latest/design.html#asyncio-workers>`_
+to it: `gthread` a fully threaded async worker using futures and `gaiohttp` a
+worker using asyncio.
+
+
+Breaking Changes
+----------------
+
+Switch QUIT and TERM signals
+++++++++++++++++++++++++++++
+
+With this change, when gunicorn receives a QUIT all the workers are
+killed immediately and exit and TERM is used for the graceful shutdown.
+
+Note: the old behaviour was based on the NGINX but the new one is more
+correct according the following doc:
+
+https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
+
+also it is complying with the way the signals are sent by heroku:
+
+https://devcenter.heroku.com/articles/python-faq#what-constraints-exist-when-developing-applications-on-heroku
+
+Deprecations
+++++++++++++
+
+`run_gunicorn`, `gunicorn_django` and `gunicorn_paster` are now
+completely deprecated and will be removed in the next release. Use the
+`gunicorn` command instead.
+
+
+Changes
+-------
+
+core
+++++
+
+- add aiohttp worker named `gaiohttp` using asyncio. Full async worker
+  on python 3.
+- fix HTTP-violating excess whitespace in write_error output
+- fix: try to log what happened in the worker after a timeout, add a
+  `worker_abort` hook on SIGABRT signal.
+- fix: save listener socket name in workers so we can handle buffered
+  keep-alive requests after the listener has closed.
+- add on_exit hook called just before exiting gunicorn.
+- add support for python 3.4
+- fix: do not swallow unexpected errors when reaping
+- fix: remove incompatible SSL option with python 2.6
+- add new async gthread worker and `--threads` options allows to set multiple
+  threads to listen on connection
+- deprecate `gunicorn_django` and `gunicorn_paster`
+- switch QUIT and TERM signal
+- reap workers in SIGCHLD handler
+- add universal wheel support
+- use `email.utils.formatdate` in gunicorn.util.http_date
+- deprecate the `--debug` option
+- fix: log exceptions that occur after response start …
+- allows loading of applications from `.pyc` files (#693)
+- fix: issue #691, raw_env config file parsing
+- use a dynamic timeout to wait for the optimal time. (Reduce power
+  usage)
+- fix python3 support when notifying the arbiter
+- add: honor $WEB_CONCURRENCY environment variable. Useful for heroku
+  setups.
+- add: include tz offset in access log
+- add: include access logs in the syslog handler.
+- add --reload option for code reloading
+- add the capability to load `gunicorn.base.Application` without the loading of
+  the arguments of the command line. It allows you to :ref:`embed gunicorn in
+  your own application <custom>`.
+- improve: set wsgi.multithread to True for async workers
+- fix logging: make sure to redirect wsgi.errors when needed
+- add: syslog logging can now be done to a unix socket
+- fix logging: don't try to redirect stdout/stderr to the logfile.
+- fix logging: don't propagate log
+- improve logging: file option can be overriden by the gunicorn options
+  `--error-logfile` and `--access-logfile` if they are given.
+- fix: don't override SERVER_* by the Host header
+- fix: handle_error
+- add more option to configure SSL
+- fix: sendfile with SSL
+- add: worker_int callback (to react on SIGTERM)
+- fix: don't depend on entry point for internal classes, now absolute
+  modules path can be given.
+- fix: Error messages are now encoded in latin1
+- fix: request line length check
+- improvement: proxy_allow_ips: Allow proxy protocol if "*" specified
+- fix: run worker's `setup` method  before setting num_workers
+- fix: FileWrapper inherit from `object` now
+- fix: Error messages are now encoded in latin1
+- fix: don't spam the console on SIGWINCH.
+- fix: logging -don't stringify T and D logging atoms (#621)
+- add support for the latest django version
+- deprecate `run_gunicorn` django option
+- fix: sys imported twice
+
+
+gevent worker
++++++++++++++
+
+- fix: make sure to stop all listeners
+- fix: monkey patching is now done in the worker
+- fix: "global name 'hub' is not defined"
+- fix: reinit `hub` on old versions of gevent
+- support gevent 1.0
+- fix: add subprocess in monkey patching
+- fix: add support for multiple listener
+
+
+eventlet worker
++++++++++++++++
+
+- fix: merge duplicate EventletWorker.init_process method (fixes #657)
+- fix: missing errno import for eventlet sendfile patch
+- fix: add support for multiple listener
+
+
+tornado worker
+++++++++++++++
+
+- add graceful stop support

+ 219 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2015-news.rst

@@ -0,0 +1,219 @@
+================
+Changelog - 2015
+================
+
+.. note::
+
+   Please see :doc:`news` for the latest changes.
+
+19.4.3 / 2015/12/30
+===================
+
+- fix: don't check if a file is writable using os.stat with SELINUX (:issue:`1171`)
+
+19.4.2 / 2015/12/29
+===================
+
+Core
+++++
+
+- improvement: handle HaltServer in manage_workers (:issue:`1095`)
+- fix: Do not rely on sendfile sending requested count (:issue:`1155`)
+- fix: claridy --no-sendfile default (:issue:`1156`)
+- fix: LoggingCatch sendfile failure from no file descriptor (:issue:`1160`)
+
+Logging
++++++++
+
+- fix: Always send access log to syslog if syslog is on
+- fix: check auth before trying to own a file (:issue:`1157`)
+
+
+Documentation
++++++++++++++
+
+- fix: Fix Slowloris broken link. (:issue:`1142`)
+- Tweak markup in faq.rst
+
+Testing
++++++++
+
+- fix: gaiohttp test (:issue:`1164`)
+
+19.4.1 / 2015/11/25
+===================
+
+- fix tornado worker (:issue:`1154`)
+
+19.4.0 / 2015/11/20
+===================
+
+Core
+++++
+
+- fix: make sure that a user is able to access to the logs after dropping a
+  privilege (:issue:`1116`)
+- improvement: inherit the `Exception` class where it needs to be (:issue:`997`)
+- fix: make sure headers are always encoded as latin1 RFC 2616 (:issue:`1102`)
+- improvement: reduce arbiter noise (:issue:`1078`)
+- fix: don't close the unix socket when the worker exit (:issue:`1088`)
+- improvement: Make last logged worker count an explicit instance var (:issue:`1078`)
+- improvement: prefix config file with its type (:issue:`836`)
+- improvement: pidfile handing (:issue:`1042`)
+- fix: catch OSError as well as ValueError on race condition (:issue:`1052`)
+- improve support of ipv6 by backporting urlparse.urlsplit from Python 2.7 to
+  Python 2.6.
+- fix: raise InvalidRequestLine when the line contains malicious data
+  (:issue:`1023`)
+- fix: fix argument to disable sendfile
+- fix: add gthread to the list of supported workers (:issue:`1011`)
+- improvement: retry socket binding up to five times upon EADDRNOTAVAIL
+  (:issue:`1004`)
+- **breaking change**: only honor headers that can be encoded in ascii to comply to
+  the RFC 7230 (See :issue:`1151`).
+
+Logging
++++++++
+
+- add new parameters to access log (:issue:`1132`)
+- fix: make sure that files handles are correctly reopened on HUP
+  (:issue:`627`)
+- include request URL in error message (:issue:`1071`)
+- get username in access logs (:issue:`1069`)
+- fix statsd logging support on Python 3 (:issue:`1010`)
+
+Testing
++++++++
+
+- use last version of mock.
+- many fixes in Travis CI support
+- miscellaneous improvements in tests
+
+Thread worker
++++++++++++++
+
+- fix: Fix self.nr usage in ThreadedWorker so that auto restart works as
+  expected (:issue:`1031`)
+
+Gevent worker
++++++++++++++
+
+- fix quit signal handling (:issue:`1128`)
+- add support for Python 3 (:issue:`1066`)
+- fix: make graceful shutdown thread-safe (:issue:`1032`)
+
+Tornado worker
+++++++++++++++
+
+- fix ssl options (:issue:`1146`, :issue:`1135`)
+- don't check timeout when stopping gracefully (:issue:`1106`)
+
+AIOHttp worker
+++++++++++++++
+
+- add SSL support (:issue:`1105`)
+
+Documentation
++++++++++++++
+
+- fix link to proc name setting (:issue:`1144`)
+- fix worker class documentation (:issue:`1141`, :issue:`1104`)
+- clarify graceful timeout documentation (:issue:`1137`)
+- don't duplicate NGINX config files examples (:issue:`1050`, :issue:`1048`)
+- add `web.py` framework example (:issue:`1117`)
+- update Debian/Ubuntu installations instructions (:issue:`1112`)
+- clarify `pythonpath` setting description (:issue:`1080`)
+- tweak some example for python3
+- clarify `sendfile` documentation
+- miscellaneous typos in source code comments (thanks!)
+- clarify why REMOTE_ADD may not be the user's IP address (:issue:`1037`)
+
+
+Misc
+++++
+
+- fix: reloader should survive SyntaxError (:issue:`994`)
+- fix: expose the reloader class to the worker.
+
+
+
+19.3.0 / 2015/03/06
+===================
+
+Core
+++++
+
+- fix: :issue:`978` make sure a listener is inheritable
+- add `check_config` class method to workers
+- fix: :issue:`983` fix select timeout in sync worker with multiple
+  connections
+- allows workers to access to the reloader. close :issue:`984`
+- raise TypeError instead of AssertionError
+
+Logging
++++++++
+
+- make Logger.loglevel a class attribute
+
+Documentation
++++++++++++++
+
+- fix: :issue:`988` fix syntax errors in examples/gunicorn_rc
+
+
+19.2.1 / 2015/02/4
+==================
+
+Logging
++++++++
+
+- expose loglevel in the Logger class
+
+AsyncIO worker (gaiohttp)
++++++++++++++++++++++++++
+
+- fix :issue:`977` fix initial crash
+
+Documentation
++++++++++++++
+
+- document security mailing-list in the contributing page.
+
+19.2 / 2015/01/30
+=================
+
+Core
+++++
+
+- optimize the sync workers when listening on a single interface
+- add `--sendfile` settings to enable/disable sendfile. fix :issue:`856` .
+- add the selectors module to the code base. :issue:`886`
+- add `--max-requests-jitter` setting to set the maximum jitter to add to the
+  max-requests setting.
+- fix :issue:`899` propagate proxy_protocol_info to keep-alive requests
+- fix :issue:`863` worker timeout: dynamic timeout has been removed
+- fix: Avoid world writable file
+
+Logging
++++++++
+
+- fix :issue:`941`  set logconfig default to paster more trivially
+- add statsd-prefix config setting: set the prefix to use when emitting statsd
+  metrics
+- :issue:`832` log to console by default
+
+Thread Worker
++++++++++++++
+
+- fix :issue:`908` make sure the worker can continue to accept requests
+
+Eventlet Worker
++++++++++++++++
+
+- fix :issue:`867` Fix eventlet shutdown to actively shut down the workers.
+
+Documentation
++++++++++++++
+
+Many improvements and fixes have been done, see the detailed changelog for
+more information.

+ 91 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2016-news.rst

@@ -0,0 +1,91 @@
+================
+Changelog - 2016
+================
+
+.. note::
+
+   Please see :doc:`news` for the latest changes
+
+19.6.0 / 2016/05/21
+===================
+
+Core & Logging
+++++++++++++++
+
+- improvement of the binary upgrade behaviour using USR2: remove file locking (:issue:`1270`)
+- add the ``--capture-output`` setting to capture stdout/stderr tot the log
+  file (:issue:`1271`)
+- Allow disabling ``sendfile()`` via the ``SENDFILE`` environment variable
+  (:issue:`1252`)
+- fix reload under pycharm (:issue:`1129`)
+
+Workers
++++++++
+
+- fix: make sure to remove the signal from the worker pipe (:issue:`1269`)
+- fix: **gthread** worker, handle removed socket in the select loop
+  (:issue:`1258`)
+
+19.5.0 / 2016/05/10
+===================
+
+Core
+++++
+
+- fix: Ensure response to HEAD request won't have message body
+- fix: lock domain socket and remove on last arbiter exit (:issue:`1220`)
+- improvement: use EnvironmentError instead of socket.error (:issue:`939`)
+- add: new ``FORWARDED_ALLOW_IPS`` environment variable (:issue:`1205`)
+- fix: infinite recursion when destroying sockets (:issue:`1219`)
+- fix: close sockets on shutdown (:issue:`922`)
+- fix: clean up sys.exc_info calls to drop circular refs (:issue:`1228`)
+- fix: do post_worker_init after load_wsgi (:issue:`1248`)
+
+Workers
++++++++
+
+- fix access logging in gaiohttp worker (:issue:`1193`)
+- eventlet: handle QUIT in a new coroutine (:issue:`1217`)
+- gevent: remove obsolete exception clauses in run (:issue:`1218`)
+- tornado: fix extra "Server" response header (:issue:`1246`)
+- fix: unblock the wait loop under python 3.5 in sync worker (:issue:`1256`)
+
+Logging
++++++++
+
+- fix: log message for listener reloading (:issue:`1181`)
+- Let logging module handle traceback printing (:issue:`1201`)
+- improvement: Allow configuring logger_class with statsd_host (:issue:`1188`)
+- fix: traceback formatting (:issue:`1235`)
+- fix: print error logs on stderr and access logs on stdout (:issue:`1184`)
+
+
+Documentation
++++++++++++++
+
+- Simplify installation instructions in gunicorn.org (:issue:`1072`)
+- Fix URL and default worker type in example_config (:issue:`1209`)
+- update django doc url to 1.8 lts (:issue:`1213`)
+- fix: miscellaneous wording corrections (:issue:`1216`)
+- Add PSF License Agreement of selectors.py to NOTICE (:issue: `1226`)
+- document LOGGING overriding (:issue:`1051`)
+- put a note that error logs are only errors from Gunicorn (:issue:`1124`)
+- add a note about the requirements of the threads workers under python 2.x (:issue:`1200`)
+- add access_log_format to config example (:issue:`1251`)
+
+Tests
++++++
+
+- Use more pytest.raises() in test_http.py
+
+
+19.4.5 / 2016/01/05
+===================
+
+- fix: NameError fileno in gunicorn.http.wsgi (:issue:`1178`)
+
+19.4.4 / 2016/01/04
+===================
+
+- fix: check if a fileobject can be used with sendfile(2) (:issue:`1174`)
+- doc: be more descriptive in errorlog option (:issue:`1173`)

+ 46 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/2017-news.rst

@@ -0,0 +1,46 @@
+================
+Changelog - 2017
+================
+
+.. note::
+
+   Please see :doc:`news` for the latest changes
+
+19.7.1 / 2017/03/21
+===================
+
+- fix: continue if SO_REUSEPORT seems to be available but fails (:issue:`1480`)
+- fix: support non-decimal values for the umask command line option (:issue:`1325`)
+
+19.7.0 / 2017/03/01
+===================
+
+- The previously deprecated ``gunicorn_django`` command has been removed.
+  Use the :ref:`gunicorn-cmd` command-line interface instead.
+- The previously deprecated ``django_settings`` setting has been removed.
+  Use the :ref:`raw-env` setting instead.
+- The default value of :ref:`ssl-version` has been changed from
+  ``ssl.PROTOCOL_TLSv1`` to ``ssl.PROTOCOL_SSLv23``.
+- fix: initialize the group access list when initgroups is set (:issue:`1297`)
+- add environment variables to gunicorn access log format (:issue:`1291`)
+- add --paste-global-conf option (:issue:`1304`)
+- fix: print access logs to STDOUT (:issue:`1184`)
+- remove upper limit on max header size config (:issue:`1313`)
+- fix: print original exception on AppImportError (:issue:`1334`)
+- use SO_REUSEPORT if available (:issue:`1344`)
+- `fix leak <https://github.com/benoitc/gunicorn/commit/b4c41481e2d5ef127199a4601417a6819053c3fd>`_ of duplicate file descriptor for bound sockets.
+- add --reload-engine option, support inotify and other backends (:issue:`1368`, :issue:`1459`)
+- fix: reject request with invalid HTTP versions
+- add ``child_exit`` callback (:issue:`1394`)
+- add support for eventlets _AlreadyHandled object (:issue:`1406`)
+- format boot tracebacks properly with reloader (:issue:`1408`)
+- refactor socket activation and fd inheritance for better support of SystemD (:issue:`1310`)
+- fix: o fds are given by default in gunicorn (:issue:`1423`)
+- add ability to pass settings to GUNICORN_CMD_ARGS environment variable which helps in container world (:issue:`1385`)
+- fix:  catch access denied to pid file (:issue:`1091`)
+-  many additions and improvements to the documentation
+
+Breaking Change
++++++++++++++++
+
+- **Python 2.6.0** is the last supported version

BIN
desktop/core/ext-py/gunicorn-19.9.0/docs/source/_static/gunicorn.png


+ 39 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/community.rst

@@ -0,0 +1,39 @@
+=========
+Community
+=========
+
+Use these channels to communicate about the project.
+
+Project Management & Discussions
+================================
+
+Gunicorn uses `GitHub for the project management <https://github.com/benoitc/gunicorn/projects>`_. GitHub issues are used
+for 3 different purposes:
+
+  * `Bug tracker <https://github.com/benoitc/gunicorn/projects/2>`_ : to check latest bug 
+  * `Forum <https://github.com/benoitc/gunicorn/projects/4>`_ : Stackoverflow-style questions about Gunicorn usage
+  * `Mailing list <https://github.com/benoitc/gunicorn/projects/3>`_ : Discussion of Gunicorn development, new features
+    and project management.  
+
+Project maintenance guidelines are avaible on the `wiki <https://github.com/benoitc/gunicorn/wiki/Project-management>`_
+.
+
+IRC
+===
+
+The Gunicorn channel is on the `Freenode <http://freenode.net/>`_ IRC
+network. You can chat with other on `#gunicorn channel
+<http://webchat.freenode.net/?channels=gunicorn>`_.
+
+Issue Tracking
+==============
+
+Bug reports, enhancement requests and tasks generally go in the `Github
+issue tracker <http://github.com/benoitc/gunicorn/issues>`_.
+
+Security Issues
+===============
+
+The security mailing list is a place to report security issues. Only
+developers are subscribed to it. To post a message to the list use the address
+to `security@gunicorn.org <mailto:security@gunicorn.org>`_ .

+ 73 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/conf.py

@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+#
+# Gunicorn documentation build configuration file
+#
+
+import os
+import sys
+import time
+
+DOCS_DIR = os.path.abspath(os.path.dirname(__file__))
+
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+# for gunicorn_ext.py
+sys.path.append(os.path.join(DOCS_DIR, os.pardir))
+sys.path.insert(0, os.path.join(DOCS_DIR, os.pardir, os.pardir))
+
+extensions = ['gunicorn_ext']
+templates_path = ['_templates']
+source_suffix = '.rst'
+master_doc = 'index'
+
+# General information about the project.
+project = u'Gunicorn'
+copyright = u'2009-%s, Benoit Chesneau' % time.strftime('%Y')
+# gunicorn version
+import gunicorn
+release = version = gunicorn.__version__
+
+exclude_patterns = []
+pygments_style = 'sphinx'
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+if not on_rtd:  # only import and set the theme if we're building docs locally
+    try:
+        import sphinx_rtd_theme
+    except ImportError:
+        html_theme = 'default'
+    else:
+        html_theme = 'sphinx_rtd_theme'
+        html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+else:
+    html_theme = 'default'
+
+html_static_path = ['_static']
+htmlhelp_basename = 'Gunicorndoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+
+}
+
+latex_documents = [
+  ('index', 'Gunicorn.tex', u'Gunicorn Documentation',
+   u'Benoit Chesneau', 'manual'),
+]
+
+
+# -- Options for manual page output --------------------------------------------
+man_pages = [
+    ('index', 'gunicorn', u'Gunicorn Documentation',
+     [u'Benoit Chesneau'], 1)
+]
+
+texinfo_documents = [
+  ('index', 'Gunicorn', u'Gunicorn Documentation',
+   u'Benoit Chesneau', 'Gunicorn', 'One line description of project.',
+   'Miscellaneous'),
+]

+ 98 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/configure.rst

@@ -0,0 +1,98 @@
+.. _configuration:
+
+======================
+Configuration Overview
+======================
+
+Gunicorn pulls configuration information from three distinct places.
+
+The first place that Gunicorn will read configuration from is the framework
+specific configuration file. Currently this only affects Paster applications.
+
+The second source of configuration information is a configuration file that is
+optionally specified on the command line. Anything specified in the Gunicorn
+config file will override any framework specific settings.
+
+Lastly, the command line arguments used to invoke Gunicorn are the final place
+considered for configuration settings. If an option is specified on the command
+line, this is the value that will be used.
+
+Once again, in order of least to most authoritative:
+    1. Framework Settings
+    2. Configuration File
+    3. Command Line
+
+
+.. note::
+
+    To check your configuration when using the command line or the
+    configuration file you can run the following command::
+
+        $ gunicorn --check-config APP_MODULE
+
+    It also allows you to know if your application can be launched.
+
+
+Command Line
+============
+
+If an option is specified on the command line, it overrides all other values
+that may have been specified in the app specific settings, or in the optional
+configuration file. Not all Gunicorn settings are available to be set from the
+command line. To see the full list of command line settings you can do the
+usual::
+
+    $ gunicorn -h
+
+There is also a ``--version`` flag available to the command line scripts that
+isn't mentioned in the list of :ref:`settings <settings>`.
+
+
+Configuration File
+==================
+
+The configuration file should be a valid Python source file. It only needs to
+be readable from the file system. More specifically, it does not need to be
+importable. Any Python is valid. Just consider that this will be run every time
+you start Gunicorn (including when you signal Gunicorn to reload).
+
+To set a parameter, just assign to it. There's no special syntax. The values
+you provide will be used for the configuration values.
+
+For instance::
+
+    import multiprocessing
+
+    bind = "127.0.0.1:8000"
+    workers = multiprocessing.cpu_count() * 2 + 1
+
+All the settings are mentioned in the :ref:`settings <settings>` list.
+
+
+Framework Settings
+==================
+
+Currently, only Paster applications have access to framework specific
+settings. If you have ideas for providing settings to WSGI applications or
+pulling information from Django's settings.py feel free to open an issue_ to
+let us know.
+
+.. _issue: https://github.com/benoitc/gunicorn/issues
+
+Paster Applications
+-------------------
+
+In your INI file, you can specify to use Gunicorn as the server like such:
+
+.. code-block:: ini
+
+    [server:main]
+    use = egg:gunicorn#main
+    host = 192.168.0.1
+    port = 80
+    workers = 2
+    proc_name = brim
+
+Any parameters that Gunicorn knows about will automatically be inserted into
+the base configuration. Remember that these will be overridden by the config
+file and/or the command line.

+ 16 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/custom.rst

@@ -0,0 +1,16 @@
+.. _custom:
+
+==================
+Custom Application
+==================
+
+.. versionadded:: 19.0
+
+Sometimes, you want to integrate Gunicorn with your WSGI application. In this
+case, you can inherit from :class:`gunicorn.app.base.BaseApplication`.
+
+Here is a small example where we create a very small WSGI app and load it with
+a custom Application:
+
+.. literalinclude:: ../../examples/standalone_app.py
+    :lines: 11-60

+ 336 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/deploy.rst

@@ -0,0 +1,336 @@
+==================
+Deploying Gunicorn
+==================
+
+We strongly recommend to use Gunicorn behind a proxy server.
+
+Nginx Configuration
+===================
+
+Although there are many HTTP proxies available, we strongly advise that you
+use Nginx_. If you choose another proxy server you need to make sure that it
+buffers slow clients when you use default Gunicorn workers. Without this
+buffering Gunicorn will be easily susceptible to denial-of-service attacks.
+You can use Hey_ to check if your proxy is behaving properly.
+
+An `example configuration`_ file for fast clients with Nginx_:
+
+.. literalinclude:: ../../examples/nginx.conf
+   :language: nginx
+   :caption: **nginx.conf**
+
+If you want to be able to handle streaming request/responses or other fancy
+features like Comet, Long polling, or Web sockets, you need to turn off the
+proxy buffering. **When you do this** you must run with one of the async worker
+classes.
+
+To turn off buffering, you only need to add ``proxy_buffering off;`` to your
+``location`` block::
+
+  ...
+  location @proxy_to_app {
+      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+      proxy_set_header Host $http_host;
+      proxy_redirect off;
+      proxy_buffering off;
+
+      proxy_pass http://app_server;
+  }
+  ...
+
+It is recommended to pass protocol information to Gunicorn. Many web
+frameworks use this information to generate URLs. Without this
+information, the application may mistakenly generate 'http' URLs in
+'https' responses, leading to mixed content warnings or broken
+applications. To configure Nginx to pass an appropriate header, add
+a ``proxy_set_header`` directive to your ``location`` block::
+
+    ...
+    proxy_set_header X-Forwarded-Proto $scheme;
+    ...
+
+If you are running Nginx on a different host than Gunicorn you need to tell
+Gunicorn to trust the ``X-Forwarded-*`` headers sent by Nginx. By default,
+Gunicorn will only trust these headers if the connection comes from localhost.
+This is to prevent a malicious client from forging these headers::
+
+    $ gunicorn -w 3 --forwarded-allow-ips="10.170.3.217,10.170.3.220" test:app
+
+When the Gunicorn host is completely firewalled from the external network such
+that all connections come from a trusted proxy (e.g. Heroku) this value can
+be set to '*'. Using this value is **potentially dangerous** if connections to
+Gunicorn may come from untrusted proxies or directly from clients since the
+application may be tricked into serving SSL-only content over an insecure
+connection.
+
+Gunicorn 19 introduced a breaking change concerning how ``REMOTE_ADDR`` is
+handled. Previous to Gunicorn 19 this was set to the value of
+``X-Forwarded-For`` if received from a trusted proxy. However, this was not in
+compliance with :rfc:`3875` which is why the ``REMOTE_ADDR`` is now the IP
+address of **the proxy** and **not the actual user**. You should instead
+configure Nginx to send the user's IP address through the ``X-Forwarded-For``
+header like this::
+
+    ...
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    ...
+
+It is also worth noting that the ``REMOTE_ADDR`` will be completely empty if
+you bind Gunicorn to a UNIX socket and not a TCP ``host:port`` tuple.
+
+Using Virtualenv
+================
+
+To serve an app from a Virtualenv_ it is generally easiest to just install
+Gunicorn directly into the Virtualenv. This will create a set of Gunicorn
+scripts for that Virtualenv which can be used to run applications normally.
+
+If you have Virtualenv installed, you should be able to do something like
+this::
+
+    $ mkdir ~/venvs/
+    $ virtualenv ~/venvs/webapp
+    $ source ~/venvs/webapp/bin/activate
+    $ pip install gunicorn
+    $ deactivate
+
+Then you just need to use one of the three Gunicorn scripts that was installed
+into ``~/venvs/webapp/bin``.
+
+Note: You can force the installation of Gunicorn in your Virtualenv by
+passing ``-I`` or ``--ignore-installed`` option to pip::
+
+     $ source ~/venvs/webapp/bin/activate
+     $ pip install -I gunicorn
+
+Monitoring
+==========
+
+.. note::
+   Make sure that when using either of these service monitors you do not
+   enable the Gunicorn's daemon mode. These monitors expect that the process
+   they launch will be the process they need to monitor. Daemonizing will
+   fork-exec which creates an unmonitored process and generally just
+   confuses the monitor services.
+
+Gaffer
+------
+
+Using Gafferd and gaffer
+++++++++++++++++++++++++
+
+Gaffer_ can be used to monitor Gunicorn. A simple configuration is::
+
+    [process:gunicorn]
+    cmd = gunicorn -w 3 test:app
+    cwd = /path/to/project
+
+Then you can easily manage Gunicorn using Gaffer_.
+
+
+Using a Procfile
+++++++++++++++++
+
+Create a ``Procfile`` in your project::
+
+    gunicorn = gunicorn -w 3 test:app
+
+You can launch any other applications that should be launched at the same time.
+
+Then you can start your Gunicorn application using Gaffer_::
+
+    gaffer start
+
+If gafferd is launched you can also load your Procfile in it directly::
+
+    gaffer load
+
+All your applications will be then supervised by gafferd.
+
+Runit
+-----
+
+A popular method for deploying Gunicorn is to have it monitored by runit_.
+Here is an `example service`_ definition::
+
+    #!/bin/sh
+
+    GUNICORN=/usr/local/bin/gunicorn
+    ROOT=/path/to/project
+    PID=/var/run/gunicorn.pid
+
+    APP=main:application
+
+    if [ -f $PID ]; then rm $PID; fi
+
+    cd $ROOT
+    exec $GUNICORN -c $ROOT/gunicorn.conf.py --pid=$PID $APP
+
+Save this as ``/etc/sv/[app_name]/run``, and make it executable
+(``chmod u+x /etc/sv/[app_name]/run``).
+Then run ``ln -s /etc/sv/[app_name] /etc/service/[app_name]``.
+If runit is installed, Gunicorn should start running automatically as soon
+as you create the symlink.
+
+If it doesn't start automatically, run the script directly to troubleshoot.
+
+Supervisor
+----------
+
+Another useful tool to monitor and control Gunicorn is Supervisor_. A
+`simple configuration`_ is::
+
+    [program:gunicorn]
+    command=/path/to/gunicorn main:application -c /path/to/gunicorn.conf.py
+    directory=/path/to/project
+    user=nobody
+    autostart=true
+    autorestart=true
+    redirect_stderr=true
+
+Upstart
+-------
+
+Using Gunicorn with upstart is simple. In this example we will run the app
+"myapp" from a virtualenv. All errors will go to
+``/var/log/upstart/myapp.log``.
+
+**/etc/init/myapp.conf**::
+
+    description "myapp"
+
+    start on (filesystem)
+    stop on runlevel [016]
+
+    respawn
+    setuid nobody
+    setgid nogroup
+    chdir /path/to/app/directory
+
+    exec /path/to/virtualenv/bin/gunicorn myapp:app
+
+Systemd
+-------
+
+A tool that is starting to be common on linux systems is Systemd_. Below are
+configurations files and instructions for using systemd to create a unix socket
+for incoming Gunicorn requests.  Systemd will listen on this socket and start
+gunicorn automatically in response to traffic.  Later in this section are 
+instructions for configuring Nginx to forward web traffic to the newly created
+unix socket:
+
+**/etc/systemd/system/gunicorn.service**::
+
+    [Unit]
+    Description=gunicorn daemon
+    Requires=gunicorn.socket
+    After=network.target
+
+    [Service]
+    PIDFile=/run/gunicorn/pid
+    User=someuser
+    Group=someuser
+    RuntimeDirectory=gunicorn
+    WorkingDirectory=/home/someuser/applicationroot
+    ExecStart=/usr/bin/gunicorn --pid /run/gunicorn/pid   \
+              --bind unix:/run/gunicorn/socket applicationname.wsgi
+    ExecReload=/bin/kill -s HUP $MAINPID
+    ExecStop=/bin/kill -s TERM $MAINPID
+    PrivateTmp=true
+
+    [Install]
+    WantedBy=multi-user.target
+
+**/etc/systemd/system/gunicorn.socket**::
+
+    [Unit]
+    Description=gunicorn socket
+
+    [Socket]
+    ListenStream=/run/gunicorn/socket
+
+    [Install]
+    WantedBy=sockets.target
+
+**/etc/tmpfiles.d/gunicorn.conf**::
+
+    d /run/gunicorn 0755 someuser somegroup -
+
+Next enable the socket so it autostarts at boot::
+
+    systemctl enable gunicorn.socket
+
+Either reboot, or start the services manually::
+
+    systemctl start gunicorn.socket
+
+
+After running ``curl --unix-socket /run/gunicorn/socket http``, Gunicorn
+should start and you should see some HTML from your server in the terminal.
+
+You must now configure your web proxy to send traffic to the new Gunicorn
+socket. Edit your ``nginx.conf`` to include the following:
+
+**/etc/nginx/nginx.conf**::
+
+    ...
+    http {
+        server {
+            listen          8000;
+            server_name     127.0.0.1;
+            location / {
+                proxy_pass http://unix:/run/gunicorn/socket;
+            }
+        }
+    }
+    ...
+
+.. note::
+
+    The listen and server_name used here are configured for a local machine.
+    In a production server you will most likely listen on port 80,
+    and use your URL as the server_name.
+    
+Now make sure you enable the nginx service so it automatically starts at boot::
+
+    systemctl enable nginx.service
+    
+Either reboot, or start Nginx with the following command::
+
+    systemctl start nginx
+    
+Now you should be able to test Nginx with Gunicorn by visiting
+http://127.0.0.1:8000/ in any web browser. Systemd is now set up.
+
+
+Logging
+=======
+
+Logging can be configured by using various flags detailed in the
+`configuration documentation`_ or by creating a `logging configuration file`_.
+Send the ``USR1`` signal to rotate logs if you are using the logrotate
+utility::
+
+    kill -USR1 $(cat /var/run/gunicorn.pid)
+
+.. note::
+   Overriding the ``LOGGING`` dictionary requires to set
+   ``disable_existing_loggers: False`` to not interfere with the Gunicorn
+   logging.
+
+.. warning::
+   Gunicorn error log is here to log errors from Gunicorn, not from another
+   application.
+
+.. _Nginx: https://nginx.org/
+.. _Hey: https://github.com/rakyll/hey
+.. _`example configuration`: https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf
+.. _runit: http://smarden.org/runit/
+.. _`example service`: https://github.com/benoitc/gunicorn/blob/master/examples/gunicorn_rc
+.. _Supervisor: http://supervisord.org/
+.. _`simple configuration`: https://github.com/benoitc/gunicorn/blob/master/examples/supervisor.conf
+.. _`configuration documentation`: http://docs.gunicorn.org/en/latest/settings.html#logging
+.. _`logging configuration file`: https://github.com/benoitc/gunicorn/blob/master/examples/logging.conf
+.. _Virtualenv: https://pypi.python.org/pypi/virtualenv
+.. _Systemd: https://www.freedesktop.org/wiki/Software/systemd/
+.. _Gaffer: https://gaffer.readthedocs.io/

+ 162 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/design.rst

@@ -0,0 +1,162 @@
+
+.. _design:
+
+======
+Design
+======
+
+A brief description of the architecture of Gunicorn.
+
+Server Model
+============
+
+Gunicorn is based on the pre-fork worker model. This means that there is a
+central master process that manages a set of worker processes. The master
+never knows anything about individual clients. All requests and responses are
+handled completely by worker processes.
+
+Master
+------
+
+The master process is a simple loop that listens for various process signals
+and reacts accordingly. It manages the list of running workers by listening
+for signals like TTIN, TTOU, and CHLD. TTIN and TTOU tell the master to
+increase or decrease the number of running workers. CHLD indicates that a child
+process has terminated, in this case the master process automatically restarts
+the failed worker.
+
+Sync Workers
+------------
+
+The most basic and the default worker type is a synchronous worker class that
+handles a single request at a time. This model is the simplest to reason about
+as any errors will affect at most a single request. Though as we describe below
+only processing a single request at a time requires some assumptions about how
+applications are programmed.
+
+``sync`` worker does not support persistent connections - each connection is
+closed after response has been sent (even if you manually add ``Keep-Alive``
+or ``Connection: keep-alive`` header in your application).
+
+Async Workers
+-------------
+
+The asynchronous workers available are based on Greenlets_ (via Eventlet_ and
+Gevent_). Greenlets are an implementation of cooperative multi-threading for
+Python. In general, an application should be able to make use of these worker
+classes with no changes.
+
+Tornado Workers
+---------------
+
+There's also a Tornado worker class. It can be used to write applications using
+the Tornado framework. Although the Tornado workers are capable of serving a
+WSGI application, this is not a recommended configuration.
+
+
+.. _asyncio-workers:
+
+AsyncIO Workers
+---------------
+
+These workers are compatible with python3. You have two kind of workers.
+
+The worker `gthread` is a threaded worker. It accepts connections in the
+main loop, accepted connections are added to the thread pool as a
+connection job. On keepalive connections are put back in the loop
+waiting for an event. If no event happen after the keep alive timeout,
+the connection is closed.
+
+The worker `gaiohttp` is a full asyncio worker using aiohttp_.
+
+.. note::
+   The ``gaiohttp`` worker requires the aiohttp_ module to be installed.
+   aiohttp_ has removed its native WSGI application support in version 2.
+   If you want to continue to use the ``gaiohttp`` worker with your WSGI
+   application (e.g. an application that uses Flask or Django), there are
+   three options available:
+
+   #. Install aiohttp_ version 1.3.5 instead of version 2::
+
+        $ pip install aiohttp==1.3.5
+
+   #. Use aiohttp_wsgi_ to wrap your WSGI application. You can take a look
+      at the `example`_ in the Gunicorn repository.
+   #. Port your application to use aiohttp_'s ``web.Application`` API.
+   #. Use the ``aiohttp.worker.GunicornWebWorker`` worker instead of the
+      deprecated ``gaiohttp`` worker.
+
+Choosing a Worker Type
+======================
+
+The default synchronous workers assume that your application is resource-bound
+in terms of CPU and network bandwidth. Generally this means that your
+application shouldn't do anything that takes an undefined amount of time. An
+example of something that takes an undefined amount of time is a request to the
+internet. At some point the external network will fail in such a way that
+clients will pile up on your servers. So, in this sense, any web application
+which makes outgoing requests to APIs will benefit from an asynchronous worker.
+
+This resource bound assumption is why we require a buffering proxy in front of
+a default configuration Gunicorn. If you exposed synchronous workers to the
+internet, a DOS attack would be trivial by creating a load that trickles data to
+the servers. For the curious, Hey_ is an example of this type of load.
+
+
+Some examples of behavior requiring asynchronous workers:
+
+  * Applications making long blocking calls (Ie, external web services)
+  * Serving requests directly to the internet
+  * Streaming requests and responses
+  * Long polling
+  * Web sockets
+  * Comet
+
+How Many Workers?
+=================
+
+DO NOT scale the number of workers to the number of clients you expect to have.
+Gunicorn should only need 4-12 worker processes to handle hundreds or thousands
+of requests per second.
+
+Gunicorn relies on the operating system to provide all of the load balancing
+when handling requests. Generally we recommend ``(2 x $num_cores) + 1`` as the
+number of workers to start off with. While not overly scientific, the formula
+is based on the assumption that for a given core, one worker will be reading
+or writing from the socket while the other worker is processing a request.
+
+Obviously, your particular hardware and application are going to affect the
+optimal number of workers. Our recommendation is to start with the above guess
+and tune using TTIN and TTOU signals while the application is under load.
+
+Always remember, there is such a thing as too many workers. After a point your
+worker processes will start thrashing system resources decreasing the
+throughput of the entire system.
+
+How Many Threads?
+===================
+
+Since Gunicorn 19, a threads option can be used to process requests in multiple
+threads. Using threads assumes use of the gthread worker. One benefit from threads
+is that requests can take longer than the worker timeout while notifying the
+master process that it is not frozen and should not be killed. Depending on the
+system, using multiple threads, multiple worker processes, or some mixture, may
+yield the best results. For example, CPython may not perform as well as Jython
+when using threads, as threading is implemented differently by each. Using
+threads instead of processes is a good way to reduce the memory footprint of
+Gunicorn, while still allowing for application upgrades using the reload
+signal, as the application code will be shared among workers but loaded only in
+the worker processes (unlike when using the preload setting, which loads the
+code in the master process).
+
+.. note::
+   Under Python 2.x, you need to install the 'futures' package to use this 
+   feature.
+
+.. _Greenlets: https://github.com/python-greenlet/greenlet
+.. _Eventlet: http://eventlet.net/
+.. _Gevent: http://www.gevent.org/
+.. _Hey: https://github.com/rakyll/hey
+.. _aiohttp: https://aiohttp.readthedocs.io/en/stable/
+.. _aiohttp_wsgi: https://aiohttp-wsgi.readthedocs.io/en/stable/index.html
+.. _`example`: https://github.com/benoitc/gunicorn/blob/master/examples/frameworks/flaskapp_aiohttp_wsgi.py

+ 199 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/faq.rst

@@ -0,0 +1,199 @@
+.. _faq:
+
+===
+FAQ
+===
+
+WSGI Bits
+=========
+
+How do I set SCRIPT_NAME?
+-------------------------
+
+By default ``SCRIPT_NAME`` is an empty string. The value could be set by
+setting ``SCRIPT_NAME`` in the environment or as an HTTP header.
+
+
+Server Stuff
+============
+
+How do I reload my application in Gunicorn?
+-------------------------------------------
+
+You can gracefully reload by sending HUP signal to gunicorn::
+
+    $ kill -HUP masterpid
+
+How might I test a proxy configuration?
+---------------------------------------
+
+The Hey_ program is a great way to test that your proxy is correctly
+buffering responses for the synchronous workers::
+
+    $ hey -n 10000 -c 100 http://127.0.0.1:5000/
+
+This runs a benchmark of 10000 requests with 100 running concurrently.
+
+How can I name processes?
+-------------------------
+
+If you install the Python package setproctitle_ Gunicorn will set the process
+names to something a bit more meaningful. This will affect the output you see
+in tools like ``ps`` and ``top``. This helps for distinguishing the master
+process as well as between masters when running more than one app on a single
+machine. See the proc_name_ setting for more information.
+
+Why is there no HTTP Keep-Alive?
+--------------------------------
+
+The default Sync workers are designed to run behind Nginx which only uses
+HTTP/1.0 with its upstream servers. If you want to deploy Gunicorn to
+handle unbuffered requests (ie, serving requests directly from the internet)
+you should use one of the async workers.
+
+.. _Hey: https://github.com/rakyll/hey
+.. _setproctitle: https://pypi.python.org/pypi/setproctitle
+.. _proc_name: settings.html#proc-name
+
+
+Worker Processes
+================
+
+How do I know which type of worker to use?
+------------------------------------------
+
+Read the :ref:`design` page for help on the various worker types.
+
+What types of workers are there?
+--------------------------------
+
+Check out the configuration docs for worker_class_.
+
+How can I figure out the best number of worker processes?
+---------------------------------------------------------
+
+Here is our recommendation for tuning the `number of workers`_.
+
+How can I change the number of workers dynamically?
+---------------------------------------------------
+
+TTIN and TTOU signals can be sent to the master to increase or decrease
+the number of workers.
+
+To increase the worker count by one::
+
+    $ kill -TTIN $masterpid
+
+To decrease the worker count by one::
+
+    $ kill -TTOU $masterpid
+
+Does Gunicorn suffer from the thundering herd problem?
+------------------------------------------------------
+
+The thundering herd problem occurs when many sleeping request handlers, which
+may be either threads or processes, wake up at the same time to handle a new
+request. Since only one handler will receive the request, the others will have
+been awakened for no reason, wasting CPU cycles. At this time, Gunicorn does
+not implement any IPC solution for coordinating between worker processes. You
+may experience high load due to this problem when using many workers or
+threads. However `a work has been started
+<https://github.com/benoitc/gunicorn/issues/792>`_ to remove this issue.
+
+.. _worker_class: settings.html#worker-class
+.. _`number of workers`: design.html#how-many-workers
+
+Why I don't see any logs in the console?
+----------------------------------------
+
+In version R19, Gunicorn doesn't log by default in the console.
+To watch the logs in the console you need to use the option ``--log-file=-``.
+In version R20, Gunicorn logs to the console by default again.
+
+Kernel Parameters
+=================
+
+When dealing with large numbers of concurrent connections there are a handful
+of kernel parameters that you might need to adjust. Generally these should only
+affect sites with a very large concurrent load. These parameters are not
+specific to Gunicorn, they would apply to any sort of network server you may be
+running.
+
+These commands are for Linux. Your particular OS may have slightly different
+parameters.
+
+How can I increase the maximum number of file descriptors?
+----------------------------------------------------------
+
+One of the first settings that usually needs to be bumped is the maximum number
+of open file descriptors for a given process. For the confused out there,
+remember that Unices treat sockets as files.
+
+::
+
+    $ sudo ulimit -n 2048
+
+How can I increase the maximum socket backlog?
+----------------------------------------------
+
+Listening sockets have an associated queue of incoming connections that are
+waiting to be accepted. If you happen to have a stampede of clients that fill
+up this queue new connections will eventually start getting dropped.
+
+::
+
+    $ sudo sysctl -w net.core.somaxconn="2048"
+
+How can I disable the use of ``sendfile()``
+-------------------------------------------
+
+Disabling the use ``sendfile()`` can be done by using the ``--no-sendfile``
+setting or by setting the environment variable ``SENDFILE`` to 0.
+
+
+
+Troubleshooting
+===============
+
+How do I fix Django reporting an ``ImproperlyConfigured`` error?
+----------------------------------------------------------------
+
+With asynchronous workers, creating URLs with the ``reverse`` function of
+``django.core.urlresolvers`` may fail. Use ``reverse_lazy`` instead.
+
+.. _blocking-os-fchmod:
+
+How do I avoid Gunicorn excessively blocking in ``os.fchmod``?
+--------------------------------------------------------------
+
+The current heartbeat system involves calling ``os.fchmod`` on temporary file
+handlers and may block a worker for arbitrary time if the directory is on a
+disk-backed filesystem. For example, by default ``/tmp`` is not mounted as
+``tmpfs`` in Ubuntu; in AWS an EBS root instance volume may sometimes hang for
+half a minute and during this time Gunicorn workers may completely block in
+``os.fchmod``. ``os.fchmod`` may introduce extra delays if the disk gets full.
+Also Gunicon may refuse to start if it can't create the files when the disk is
+full.
+
+Currently to avoid these problems you can create a ``tmpfs`` mount (for a new
+directory or for ``/tmp``) and pass its path to ``--worker-tmp-dir``. First,
+check whether your ``/tmp`` is disk-backed or RAM-backed::
+
+    $ df /tmp
+    Filesystem     1K-blocks    Used Available Use% Mounted on
+    /dev/xvda1           ...     ...       ...  ... /
+
+No luck. Let's create a new ``tmpfs`` mount::
+
+    sudo cp /etc/fstab /etc/fstab.orig
+    sudo mkdir /mem
+    echo 'tmpfs       /mem tmpfs defaults,size=64m,mode=1777,noatime,comment=for-gunicorn 0 0' | sudo tee -a /etc/fstab
+    sudo mount /mem
+
+Check the result::
+
+    $ df /mem
+    Filesystem     1K-blocks  Used Available Use% Mounted on
+    tmpfs              65536     0     65536   0% /mem
+
+Now you can set ``--worker-tmp-dir /mem``.

+ 46 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/index.rst

@@ -0,0 +1,46 @@
+======================
+Gunicorn - WSGI server
+======================
+
+.. image:: _static/gunicorn.png
+
+:Website: http://gunicorn.org
+:Source code: https://github.com/benoitc/gunicorn
+:Issue tracker: https://github.com/benoitc/gunicorn/issues
+:IRC: ``#gunicorn`` on Freenode
+:Usage questions: https://github.com/benoitc/gunicorn/issues
+
+Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork
+worker model ported from Ruby's Unicorn project. The Gunicorn server is broadly
+compatible with various web frameworks, simply implemented, light on server
+resources, and fairly speedy.
+
+Features
+--------
+
+* Natively supports WSGI, Django, and Paster
+* Automatic worker process management
+* Simple Python configuration
+* Multiple worker configurations
+* Various server hooks for extensibility
+* Compatible with Python 2.x >= 2.6 or 3.x >= 3.2
+
+
+Contents
+--------
+
+.. toctree::
+    :maxdepth: 2
+
+    install
+    run
+    configure
+    settings
+    instrumentation
+    deploy
+    signals
+    custom
+    design
+    faq
+    community
+    news

+ 144 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/install.rst

@@ -0,0 +1,144 @@
+============
+Installation
+============
+
+.. highlight:: bash
+
+:Requirements: **Python 2.x >= 2.6** or **Python 3.x >= 3.2**
+
+To install the latest released version of Gunicorn::
+
+  $ pip install gunicorn
+
+From Source
+===========
+
+You can install Gunicorn from source just as you would install any other
+Python package::
+
+    $ pip install git+https://github.com/benoitc/gunicorn.git
+
+This will allow you to keep up to date with development on GitHub::
+
+    $ pip install -U git+https://github.com/benoitc/gunicorn.git
+
+
+Async Workers
+=============
+
+You may also want to install Eventlet_ or Gevent_ if you expect that your
+application code may need to pause for extended periods of time during request
+processing. Check out the `design docs`_ for more information on when you'll
+want to consider one of the alternate worker types.
+
+::
+
+    $ pip install greenlet            # Required for both
+    $ pip install eventlet            # For eventlet workers
+    $ pip install gunicorn[eventlet]  # Or, using extra
+    $ pip install gevent              # For gevent workers
+    $ pip install gunicorn[gevent]    # Or, using extra
+
+.. note::
+    Both require ``greenlet``, which should get installed automatically,
+    If its installation fails, you probably need to install
+    the Python headers. These headers are available in most package
+    managers. On Ubuntu the package name for ``apt-get`` is
+    ``python-dev``.
+
+    Gevent_ also requires that ``libevent`` 1.4.x or 2.0.4 is installed.
+    This could be a more recent version than what is available in your
+    package manager. If Gevent_ fails to build even with libevent_
+    installed, this is the most likely reason.
+
+
+Debian GNU/Linux
+================
+
+If you are using Debian GNU/Linux and it is recommended that you use
+system packages to install Gunicorn except maybe when you want to use
+different versions of Gunicorn with virtualenv. This has a number of
+advantages:
+
+* Zero-effort installation: Automatically starts multiple Gunicorn instances
+  based on configurations defined in ``/etc/gunicorn.d``.
+
+* Sensible default locations for logs (``/var/log/gunicorn``). Logs
+  can be automatically rotated and compressed using ``logrotate``.
+
+* Improved security: Can easily run each Gunicorn instance with a dedicated
+  UNIX user/group.
+
+* Sensible upgrade path: Upgrades to newer versions result in less downtime,
+  handle conflicting changes in configuration options, and can be quickly
+  rolled back in case of incompatibility. The package can also be purged
+  entirely from the system in seconds.
+
+stable ("stretch")
+------------------
+
+The version of Gunicorn in the Debian_ "stable" distribution is 19.6.0 (June
+2017). You can install it using::
+
+    $ sudo apt-get install gunicorn
+
+You can also use the most recent version by using `Debian Backports`_.
+First, copy the following line to your ``/etc/apt/sources.list``::
+
+    deb http://ftp.debian.org/debian stretch-backports main
+
+Then, update your local package lists::
+
+    $ sudo apt-get update
+
+You can then install the latest version using::
+
+    $ sudo apt-get -t stretch-backports install gunicorn
+
+oldstable ("jessie")
+--------------------
+
+The version of Gunicorn in the Debian_ "oldstable" distribution is 19.0 (June
+2014). you can install it using::
+
+    $ sudo apt-get install gunicorn
+
+You can also use the most recent version by using `Debian Backports`_.
+First, copy the following line to your ``/etc/apt/sources.list``::
+
+    deb http://ftp.debian.org/debian jessie-backports main
+
+Then, update your local package lists::
+
+    $ sudo apt-get update
+
+You can then install the latest version using::
+
+    $ sudo apt-get -t jessie-backports install gunicorn
+
+Testing ("buster") / Unstable ("sid")
+-------------------------------------
+
+"buster" and "sid" contain the latest released version of Gunicorn. You can
+install it in the usual way::
+
+    $ sudo apt-get install gunicorn
+
+
+Ubuntu
+======
+
+Ubuntu_ 12.04 (trusty) or later contains Gunicorn package by default so that
+you can install it in the usual way::
+
+    $ sudo apt-get update
+    $ sudo apt-get install gunicorn
+
+
+.. _`design docs`: design.html
+.. _Eventlet: http://eventlet.net
+.. _Gevent: http://www.gevent.org/
+.. _libevent: http://libevent.org/
+.. _Debian: https://www.debian.org/
+.. _`Debian Backports`: https://backports.debian.org/
+.. _Ubuntu: https://www.ubuntu.com/

+ 36 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/instrumentation.rst

@@ -0,0 +1,36 @@
+.. _instrumentation:
+
+===============
+Instrumentation
+===============
+
+.. versionadded:: 19.1
+
+Gunicorn provides an optional instrumentation of the arbiter and
+workers using the statsD_ protocol over UDP. Thanks to the
+``gunicorn.instrument.statsd`` module, Gunicorn becomes a statsD client.
+The use of UDP cleanly isolates Gunicorn from the receiving end of the statsD
+metrics so that instrumentation does not cause Gunicorn to be held up by a slow
+statsD consumer.
+
+To use statsD, just tell Gunicorn where the statsD server is:
+
+.. code-block:: bash
+
+    $ gunicorn --statsd-host=localhost:8125 --statsd-prefix=service.app ...
+
+The ``Statsd`` logger overrides ``gunicorn.glogging.Logger`` to track
+all requests. The following metrics are generated:
+
+* ``gunicorn.requests``: request rate per second
+* ``gunicorn.request.duration``: histogram of request duration (in millisecond)
+* ``gunicorn.workers``: number of workers managed by the arbiter (gauge)
+* ``gunicorn.log.critical``: rate of critical log messages
+* ``gunicorn.log.error``: rate of error log messages
+* ``gunicorn.log.warning``: rate of warning log messages
+* ``gunicorn.log.exception``: rate of exceptional log messages
+
+See the statsd-host_ setting for more information.
+
+.. _statsd-host: settings.html#statsd-host
+.. _statsD: https://github.com/etsy/statsd

+ 80 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/news.rst

@@ -0,0 +1,80 @@
+=========
+Changelog
+=========
+
+19.9.0 / 2018/07/03
+===================
+
+- fix: address a regression that prevented syslog support from working
+  (:issue:`1668`, :pr:`1773`)
+- fix: correctly set `REMOTE_ADDR` on versions of Python 3 affected by
+  `Python Issue 30205 <https://bugs.python.org/issue30205>`_
+  (:issue:`1755`, :pr:`1796`)
+- fix: show zero response length correctly in access log (:pr:`1787`)
+- fix: prevent raising :exc:`AttributeError` when ``--reload`` is not passed
+  in case of a :exc:`SyntaxError` raised from the WSGI application.
+  (:issue:`1805`, :pr:`1806`)
+- The internal module ``gunicorn.workers.async`` was renamed to ``gunicorn.workers.base_async``
+  since ``async`` is now a reserved word in Python 3.7.
+  (:pr:`1527`)
+
+19.8.1 / 2018/04/30
+===================
+
+- fix: secure scheme headers when bound to a unix socket
+  (:issue:`1766`, :pr:`1767`)
+
+19.8.0 / 2018/04/28
+===================
+
+- Eventlet 0.21.0 support (:issue:`1584`)
+- Tornado 5 support (:issue:`1728`, :pr:`1752`)
+- support watching additional files with ``--reload-extra-file``
+  (:pr:`1527`)
+- support configuring logging with a dictionary with ``--logging-config-dict``
+  (:issue:`1087`, :pr:`1110`, :pr:`1602`)
+- add support for the ``--config`` flag in the ``GUNICORN_CMD_ARGS`` environment
+  variable (:issue:`1576`, :pr:`1581`)
+- disable ``SO_REUSEPORT`` by default and add the ``--reuse-port`` setting
+  (:issue:`1553`, :issue:`1603`, :pr:`1669`)
+- fix: installing `inotify` on MacOS no longer breaks the reloader
+  (:issue:`1540`, :pr:`1541`)
+- fix: do not throw ``TypeError`` when ``SO_REUSEPORT`` is not available
+  (:issue:`1501`, :pr:`1491`)
+- fix: properly decode HTTP paths containing certain non-ASCII characters
+  (:issue:`1577`, :pr:`1578`)
+- fix: remove whitespace when logging header values under gevent (:pr:`1607`)
+- fix: close unlinked temporary files (:issue:`1327`, :pr:`1428`)
+- fix: parse ``--umask=0`` correctly (:issue:`1622`, :pr:`1632`)
+- fix: allow loading applications using relative file paths
+  (:issue:`1349`, :pr:`1481`)
+- fix: force blocking mode on the gevent sockets (:issue:`880`, :pr:`1616`)
+- fix: preserve leading `/` in request path (:issue:`1512`, :pr:`1511`)
+- fix: forbid contradictory secure scheme headers
+- fix: handle malformed basic authentication headers in access log
+  (:issue:`1683`, :pr:`1684`)
+- fix: defer handling of ``USR1`` signal to a new greenlet under gevent
+  (:issue:`1645`, :pr:`1651`)
+- fix: the threaded worker would sometimes close the wrong keep-alive
+  connection under Python 2 (:issue:`1698`, :pr:`1699`)
+- fix: re-open log files on ``USR1`` signal using ``handler._open`` to
+  support subclasses of ``FileHandler`` (:issue:`1739`, :pr:`1742`)
+- deprecation: the ``gaiohttp`` worker is deprecated, see the
+  :ref:`worker-class` documentation for more information
+  (:issue:`1338`, :pr:`1418`, :pr:`1569`)
+
+
+History
+=======
+
+.. toctree::
+   :titlesonly:
+
+   2017-news
+   2016-news
+   2015-news
+   2014-news
+   2013-news
+   2012-news
+   2011-news
+   2010-news

+ 123 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/run.rst

@@ -0,0 +1,123 @@
+================
+Running Gunicorn
+================
+
+.. highlight:: bash
+
+You can run Gunicorn by using commands or integrate with Django or Paster. For
+deploying Gunicorn in production see :doc:`deploy`.
+
+Commands
+========
+
+After installing Gunicorn you will have access to the command line script
+``gunicorn``.
+
+.. _gunicorn-cmd:
+
+gunicorn
+--------
+
+Basic usage::
+
+    $ gunicorn [OPTIONS] APP_MODULE
+
+Where ``APP_MODULE`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
+module name can be a full dotted path. The variable name refers to a WSGI
+callable that should be found in the specified module.
+
+Example with the test app:
+
+.. code-block:: python
+
+    def app(environ, start_response):
+        """Simplest possible application object"""
+        data = b'Hello, World!\n'
+        status = '200 OK'
+        response_headers = [
+            ('Content-type', 'text/plain'),
+            ('Content-Length', str(len(data)))
+        ]
+        start_response(status, response_headers)
+        return iter([data])
+
+You can now run the app with the following command::
+
+    $ gunicorn --workers=2 test:app
+
+
+Commonly Used Arguments
+^^^^^^^^^^^^^^^^^^^^^^^
+
+* ``-c CONFIG, --config=CONFIG`` - Specify a config file in the form
+  ``$(PATH)``, ``file:$(PATH)``, or ``python:$(MODULE_NAME)``.
+* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
+  can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, or ``unix:$(PATH)``.
+  An IP is a valid ``$(HOST)``.
+* ``-w WORKERS, --workers=WORKERS`` - The number of worker processes. This
+  number should generally be between 2-4 workers per core in the server.
+  Check the :ref:`faq` for ideas on tuning this parameter.
+* ``-k WORKERCLASS, --worker-class=WORKERCLASS`` - The type of worker process
+  to run. You'll definitely want to read the production page for the
+  implications of this parameter. You can set this to ``$(NAME)``
+  where ``$(NAME)`` is one of ``sync``, ``eventlet``, ``gevent``,
+  ``tornado``, ``gthread``, ``gaiohttp`` (deprecated).
+  ``sync`` is the default. See the :ref:`worker-class` documentation for more
+  information.
+* ``-n APP_NAME, --name=APP_NAME`` - If setproctitle_ is installed you can
+  adjust the name of Gunicorn process as they appear in the process system
+  table (which affects tools like ``ps`` and ``top``).
+
+Settings can be specified by using environment variable
+:ref:`GUNICORN_CMD_ARGS <settings>`.
+
+See :ref:`configuration` and :ref:`settings` for detailed usage.
+
+.. _setproctitle: https://pypi.python.org/pypi/setproctitle
+
+Integration
+===========
+
+We also provide integration for both Django and Paster applications.
+
+Django
+------
+
+Gunicorn will look for a WSGI callable named ``application`` if not specified.
+So for a typical Django project, invoking Gunicorn would look like::
+
+    $ gunicorn myproject.wsgi
+
+
+.. note::
+
+   This requires that your project be on the Python path; the simplest way to
+   ensure that is to run this command from the same directory as your
+   ``manage.py`` file.
+
+You can use the
+`--env <http://docs.gunicorn.org/en/latest/settings.html#raw-env>`_ option
+to set the path to load the settings. In case you need it you can also
+add your application path to ``PYTHONPATH`` using the
+`--pythonpath <http://docs.gunicorn.org/en/latest/settings.html#pythonpath>`_
+option::
+
+    $ gunicorn --env DJANGO_SETTINGS_MODULE=myproject.settings myproject.wsgi
+
+Paste
+-----
+
+If you are a user/developer of a paste-compatible framework/app (as
+Pyramid, Pylons and Turbogears) you can use the
+`--paste <http://docs.gunicorn.org/en/latest/settings.html#paste>`_ option
+to run your application.
+
+For example::
+
+    $ gunicorn --paste development.ini -b :8080 --chdir /path/to/project
+
+Or use a different application::
+
+    $ gunicorn --paste development.ini#admin -b :8080 --chdir /path/to/project
+
+It is all here. No configuration files nor additional Python modules to write!

+ 1308 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/settings.rst

@@ -0,0 +1,1308 @@
+.. Please update gunicorn/config.py instead.
+
+.. _settings:
+
+Settings
+========
+
+This is an exhaustive list of settings for Gunicorn. Some settings are only
+able to be set from a configuration file. The setting name is what should be
+used in the configuration file. The command line arguments are listed as well
+for reference on setting at the command line.
+
+.. note::
+
+    Settings can be specified by using environment variable
+    ``GUNICORN_CMD_ARGS``. All available command line arguments can be used.
+    For example, to specify the bind address and number of workers::
+
+        $ GUNICORN_CMD_ARGS="--bind=127.0.0.1 --workers=3" gunicorn app:app
+
+    .. versionadded:: 19.7
+
+Config File
+-----------
+
+.. _config:
+
+config
+~~~~~~
+
+* ``-c CONFIG, --config CONFIG``
+* ``None``
+
+The Gunicorn config file.
+
+A string of the form ``PATH``, ``file:PATH``, or ``python:MODULE_NAME``.
+
+Only has an effect when specified on the command line or as part of an
+application specific configuration.
+
+.. versionchanged:: 19.4
+   Loading the config from a Python module requires the ``python:``
+   prefix.
+
+Debugging
+---------
+
+.. _reload:
+
+reload
+~~~~~~
+
+* ``--reload``
+* ``False``
+
+Restart workers when code changes.
+
+This setting is intended for development. It will cause workers to be
+restarted whenever application code changes.
+
+The reloader is incompatible with application preloading. When using a
+paste configuration be sure that the server block does not import any
+application code or the reload will not work as designed.
+
+The default behavior is to attempt inotify with a fallback to file
+system polling. Generally, inotify should be preferred if available
+because it consumes less system resources.
+
+.. note::
+   In order to use the inotify reloader, you must have the ``inotify``
+   package installed.
+
+.. _reload-engine:
+
+reload_engine
+~~~~~~~~~~~~~
+
+* ``--reload-engine STRING``
+* ``auto``
+
+The implementation that should be used to power :ref:`reload`.
+
+Valid engines are:
+
+* 'auto'
+* 'poll'
+* 'inotify' (requires inotify)
+
+.. versionadded:: 19.7
+
+.. _reload-extra-files:
+
+reload_extra_files
+~~~~~~~~~~~~~~~~~~
+
+* ``--reload-extra-file FILES``
+* ``[]``
+
+Extends :ref:`reload` option to also watch and reload on additional files
+(e.g., templates, configurations, specifications, etc.).
+
+.. versionadded:: 19.8
+
+.. _spew:
+
+spew
+~~~~
+
+* ``--spew``
+* ``False``
+
+Install a trace function that spews every line executed by the server.
+
+This is the nuclear option.
+
+.. _check-config:
+
+check_config
+~~~~~~~~~~~~
+
+* ``--check-config``
+* ``False``
+
+Check the configuration.
+
+Logging
+-------
+
+.. _accesslog:
+
+accesslog
+~~~~~~~~~
+
+* ``--access-logfile FILE``
+* ``None``
+
+The Access log file to write to.
+
+``'-'`` means log to stdout.
+
+.. _disable-redirect-access-to-syslog:
+
+disable_redirect_access_to_syslog
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* ``--disable-redirect-access-to-syslog``
+* ``False``
+
+Disable redirect access logs to syslog.
+
+.. versionadded:: 19.8
+
+.. _access-log-format:
+
+access_log_format
+~~~~~~~~~~~~~~~~~
+
+* ``--access-logformat STRING``
+* ``%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"``
+
+The access log format.
+
+===========  ===========
+Identifier   Description
+===========  ===========
+h            remote address
+l            ``'-'``
+u            user name
+t            date of the request
+r            status line (e.g. ``GET / HTTP/1.1``)
+m            request method
+U            URL path without query string
+q            query string
+H            protocol
+s            status
+B            response length
+b            response length or ``'-'`` (CLF format)
+f            referer
+a            user agent
+T            request time in seconds
+D            request time in microseconds
+L            request time in decimal seconds
+p            process ID
+{Header}i    request header
+{Header}o    response header
+{Variable}e  environment variable
+===========  ===========
+
+.. _errorlog:
+
+errorlog
+~~~~~~~~
+
+* ``--error-logfile FILE, --log-file FILE``
+* ``-``
+
+The Error log file to write to.
+
+Using ``'-'`` for FILE makes gunicorn log to stderr.
+
+.. versionchanged:: 19.2
+   Log to stderr by default.
+
+.. _loglevel:
+
+loglevel
+~~~~~~~~
+
+* ``--log-level LEVEL``
+* ``info``
+
+The granularity of Error log outputs.
+
+Valid level names are:
+
+* debug
+* info
+* warning
+* error
+* critical
+
+.. _capture-output:
+
+capture_output
+~~~~~~~~~~~~~~
+
+* ``--capture-output``
+* ``False``
+
+Redirect stdout/stderr to specified file in :ref:`errorlog`.
+
+.. versionadded:: 19.6
+
+.. _logger-class:
+
+logger_class
+~~~~~~~~~~~~
+
+* ``--logger-class STRING``
+* ``gunicorn.glogging.Logger``
+
+The logger you want to use to log events in Gunicorn.
+
+The default class (``gunicorn.glogging.Logger``) handle most of
+normal usages in logging. It provides error and access logging.
+
+You can provide your own logger by giving Gunicorn a
+Python path to a subclass like ``gunicorn.glogging.Logger``.
+
+.. _logconfig:
+
+logconfig
+~~~~~~~~~
+
+* ``--log-config FILE``
+* ``None``
+
+The log config file to use.
+Gunicorn uses the standard Python logging module's Configuration
+file format.
+
+.. _logconfig-dict:
+
+logconfig_dict
+~~~~~~~~~~~~~~
+
+* ``--log-config-dict``
+* ``{}``
+
+The log config dictionary to use, using the standard Python
+logging module's dictionary configuration format. This option
+takes precedence over the :ref:`logconfig` option, which uses the
+older file configuration format.
+
+Format: https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig
+
+.. versionadded:: 19.8
+
+.. _syslog-addr:
+
+syslog_addr
+~~~~~~~~~~~
+
+* ``--log-syslog-to SYSLOG_ADDR``
+* ``unix:///var/run/syslog``
+
+Address to send syslog messages.
+
+Address is a string of the form:
+
+* ``unix://PATH#TYPE`` : for unix domain socket. ``TYPE`` can be ``stream``
+  for the stream driver or ``dgram`` for the dgram driver.
+  ``stream`` is the default.
+* ``udp://HOST:PORT`` : for UDP sockets
+* ``tcp://HOST:PORT`` : for TCP sockets
+
+.. _syslog:
+
+syslog
+~~~~~~
+
+* ``--log-syslog``
+* ``False``
+
+Send *Gunicorn* logs to syslog.
+
+.. versionchanged:: 19.8
+   You can now disable sending access logs by using the
+   :ref:`disable-redirect-access-to-syslog` setting.
+
+.. _syslog-prefix:
+
+syslog_prefix
+~~~~~~~~~~~~~
+
+* ``--log-syslog-prefix SYSLOG_PREFIX``
+* ``None``
+
+Makes Gunicorn use the parameter as program-name in the syslog entries.
+
+All entries will be prefixed by ``gunicorn.<prefix>``. By default the
+program name is the name of the process.
+
+.. _syslog-facility:
+
+syslog_facility
+~~~~~~~~~~~~~~~
+
+* ``--log-syslog-facility SYSLOG_FACILITY``
+* ``user``
+
+Syslog facility name
+
+.. _enable-stdio-inheritance:
+
+enable_stdio_inheritance
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+* ``-R, --enable-stdio-inheritance``
+* ``False``
+
+Enable stdio inheritance.
+
+Enable inheritance for stdio file descriptors in daemon mode.
+
+Note: To disable the Python stdout buffering, you can to set the user
+environment variable ``PYTHONUNBUFFERED`` .
+
+.. _statsd-host:
+
+statsd_host
+~~~~~~~~~~~
+
+* ``--statsd-host STATSD_ADDR``
+* ``None``
+
+``host:port`` of the statsd server to log to.
+
+.. versionadded:: 19.1
+
+.. _statsd-prefix:
+
+statsd_prefix
+~~~~~~~~~~~~~
+
+* ``--statsd-prefix STATSD_PREFIX``
+* ``(empty string)``
+
+Prefix to use when emitting statsd metrics (a trailing ``.`` is added,
+if not provided).
+
+.. versionadded:: 19.2
+
+Process Naming
+--------------
+
+.. _proc-name:
+
+proc_name
+~~~~~~~~~
+
+* ``-n STRING, --name STRING``
+* ``None``
+
+A base to use with setproctitle for process naming.
+
+This affects things like ``ps`` and ``top``. If you're going to be
+running more than one instance of Gunicorn you'll probably want to set a
+name to tell them apart. This requires that you install the setproctitle
+module.
+
+If not set, the *default_proc_name* setting will be used.
+
+.. _default-proc-name:
+
+default_proc_name
+~~~~~~~~~~~~~~~~~
+
+* ``gunicorn``
+
+Internal setting that is adjusted for each type of application.
+
+SSL
+---
+
+.. _keyfile:
+
+keyfile
+~~~~~~~
+
+* ``--keyfile FILE``
+* ``None``
+
+SSL key file
+
+.. _certfile:
+
+certfile
+~~~~~~~~
+
+* ``--certfile FILE``
+* ``None``
+
+SSL certificate file
+
+.. _ssl-version:
+
+ssl_version
+~~~~~~~~~~~
+
+* ``--ssl-version``
+* ``_SSLMethod.PROTOCOL_TLS``
+
+SSL version to use (see stdlib ssl module's)
+
+.. versionchanged:: 19.7
+   The default value has been changed from ``ssl.PROTOCOL_TLSv1`` to
+   ``ssl.PROTOCOL_SSLv23``.
+
+.. _cert-reqs:
+
+cert_reqs
+~~~~~~~~~
+
+* ``--cert-reqs``
+* ``VerifyMode.CERT_NONE``
+
+Whether client certificate is required (see stdlib ssl module's)
+
+.. _ca-certs:
+
+ca_certs
+~~~~~~~~
+
+* ``--ca-certs FILE``
+* ``None``
+
+CA certificates file
+
+.. _suppress-ragged-eofs:
+
+suppress_ragged_eofs
+~~~~~~~~~~~~~~~~~~~~
+
+* ``--suppress-ragged-eofs``
+* ``True``
+
+Suppress ragged EOFs (see stdlib ssl module's)
+
+.. _do-handshake-on-connect:
+
+do_handshake_on_connect
+~~~~~~~~~~~~~~~~~~~~~~~
+
+* ``--do-handshake-on-connect``
+* ``False``
+
+Whether to perform SSL handshake on socket connect (see stdlib ssl module's)
+
+.. _ciphers:
+
+ciphers
+~~~~~~~
+
+* ``--ciphers``
+* ``TLSv1``
+
+Ciphers to use (see stdlib ssl module's)
+
+Security
+--------
+
+.. _limit-request-line:
+
+limit_request_line
+~~~~~~~~~~~~~~~~~~
+
+* ``--limit-request-line INT``
+* ``4094``
+
+The maximum size of HTTP request line in bytes.
+
+This parameter is used to limit the allowed size of a client's
+HTTP request-line. Since the request-line consists of the HTTP
+method, URI, and protocol version, this directive places a
+restriction on the length of a request-URI allowed for a request
+on the server. A server needs this value to be large enough to
+hold any of its resource names, including any information that
+might be passed in the query part of a GET request. Value is a number
+from 0 (unlimited) to 8190.
+
+This parameter can be used to prevent any DDOS attack.
+
+.. _limit-request-fields:
+
+limit_request_fields
+~~~~~~~~~~~~~~~~~~~~
+
+* ``--limit-request-fields INT``
+* ``100``
+
+Limit the number of HTTP headers fields in a request.
+
+This parameter is used to limit the number of headers in a request to
+prevent DDOS attack. Used with the *limit_request_field_size* it allows
+more safety. By default this value is 100 and can't be larger than
+32768.
+
+.. _limit-request-field-size:
+
+limit_request_field_size
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+* ``--limit-request-field_size INT``
+* ``8190``
+
+Limit the allowed size of an HTTP request header field.
+
+Value is a positive number or 0. Setting it to 0 will allow unlimited
+header field sizes.
+
+.. warning::
+   Setting this parameter to a very high or unlimited value can open
+   up for DDOS attacks.
+
+Server Hooks
+------------
+
+.. _on-starting:
+
+on_starting
+~~~~~~~~~~~
+
+*  ::
+
+        def on_starting(server):
+            pass
+
+Called just before the master process is initialized.
+
+The callable needs to accept a single instance variable for the Arbiter.
+
+.. _on-reload:
+
+on_reload
+~~~~~~~~~
+
+*  ::
+
+        def on_reload(server):
+            pass
+
+Called to recycle workers during a reload via SIGHUP.
+
+The callable needs to accept a single instance variable for the Arbiter.
+
+.. _when-ready:
+
+when_ready
+~~~~~~~~~~
+
+*  ::
+
+        def when_ready(server):
+            pass
+
+Called just after the server is started.
+
+The callable needs to accept a single instance variable for the Arbiter.
+
+.. _pre-fork:
+
+pre_fork
+~~~~~~~~
+
+*  ::
+
+        def pre_fork(server, worker):
+            pass
+
+Called just before a worker is forked.
+
+The callable needs to accept two instance variables for the Arbiter and
+new Worker.
+
+.. _post-fork:
+
+post_fork
+~~~~~~~~~
+
+*  ::
+
+        def post_fork(server, worker):
+            pass
+
+Called just after a worker has been forked.
+
+The callable needs to accept two instance variables for the Arbiter and
+new Worker.
+
+.. _post-worker-init:
+
+post_worker_init
+~~~~~~~~~~~~~~~~
+
+*  ::
+
+        def post_worker_init(worker):
+            pass
+
+Called just after a worker has initialized the application.
+
+The callable needs to accept one instance variable for the initialized
+Worker.
+
+.. _worker-int:
+
+worker_int
+~~~~~~~~~~
+
+*  ::
+
+        def worker_int(worker):
+            pass
+
+Called just after a worker exited on SIGINT or SIGQUIT.
+
+The callable needs to accept one instance variable for the initialized
+Worker.
+
+.. _worker-abort:
+
+worker_abort
+~~~~~~~~~~~~
+
+*  ::
+
+        def worker_abort(worker):
+            pass
+
+Called when a worker received the SIGABRT signal.
+
+This call generally happens on timeout.
+
+The callable needs to accept one instance variable for the initialized
+Worker.
+
+.. _pre-exec:
+
+pre_exec
+~~~~~~~~
+
+*  ::
+
+        def pre_exec(server):
+            pass
+
+Called just before a new master process is forked.
+
+The callable needs to accept a single instance variable for the Arbiter.
+
+.. _pre-request:
+
+pre_request
+~~~~~~~~~~~
+
+*  ::
+
+        def pre_request(worker, req):
+            worker.log.debug("%s %s" % (req.method, req.path))
+
+Called just before a worker processes the request.
+
+The callable needs to accept two instance variables for the Worker and
+the Request.
+
+.. _post-request:
+
+post_request
+~~~~~~~~~~~~
+
+*  ::
+
+        def post_request(worker, req, environ, resp):
+            pass
+
+Called after a worker processes the request.
+
+The callable needs to accept two instance variables for the Worker and
+the Request.
+
+.. _child-exit:
+
+child_exit
+~~~~~~~~~~
+
+*  ::
+
+        def child_exit(server, worker):
+            pass
+
+Called just after a worker has been exited, in the master process.
+
+The callable needs to accept two instance variables for the Arbiter and
+the just-exited Worker.
+
+.. versionadded:: 19.7
+
+.. _worker-exit:
+
+worker_exit
+~~~~~~~~~~~
+
+*  ::
+
+        def worker_exit(server, worker):
+            pass
+
+Called just after a worker has been exited, in the worker process.
+
+The callable needs to accept two instance variables for the Arbiter and
+the just-exited Worker.
+
+.. _nworkers-changed:
+
+nworkers_changed
+~~~~~~~~~~~~~~~~
+
+*  ::
+
+        def nworkers_changed(server, new_value, old_value):
+            pass
+
+Called just after *num_workers* has been changed.
+
+The callable needs to accept an instance variable of the Arbiter and
+two integers of number of workers after and before change.
+
+If the number of workers is set for the first time, *old_value* would
+be ``None``.
+
+.. _on-exit:
+
+on_exit
+~~~~~~~
+
+*  ::
+
+        def on_exit(server):
+            pass
+
+Called just before exiting Gunicorn.
+
+The callable needs to accept a single instance variable for the Arbiter.
+
+Server Mechanics
+----------------
+
+.. _preload-app:
+
+preload_app
+~~~~~~~~~~~
+
+* ``--preload``
+* ``False``
+
+Load application code before the worker processes are forked.
+
+By preloading an application you can save some RAM resources as well as
+speed up server boot times. Although, if you defer application loading
+to each worker process, you can reload your application code easily by
+restarting workers.
+
+.. _sendfile:
+
+sendfile
+~~~~~~~~
+
+* ``--no-sendfile``
+* ``None``
+
+Disables the use of ``sendfile()``.
+
+If not set, the value of the ``SENDFILE`` environment variable is used
+to enable or disable its usage.
+
+.. versionadded:: 19.2
+.. versionchanged:: 19.4
+   Swapped ``--sendfile`` with ``--no-sendfile`` to actually allow
+   disabling.
+.. versionchanged:: 19.6
+   added support for the ``SENDFILE`` environment variable
+
+.. _reuse-port:
+
+reuse_port
+~~~~~~~~~~
+
+* ``--reuse-port``
+* ``False``
+
+Set the ``SO_REUSEPORT`` flag on the listening socket.
+
+.. versionadded:: 19.8
+
+.. _chdir:
+
+chdir
+~~~~~
+
+* ``--chdir``
+* ``/Users/randall/src/gunicorn/docs/source``
+
+Chdir to specified directory before apps loading.
+
+.. _daemon:
+
+daemon
+~~~~~~
+
+* ``-D, --daemon``
+* ``False``
+
+Daemonize the Gunicorn process.
+
+Detaches the server from the controlling terminal and enters the
+background.
+
+.. _raw-env:
+
+raw_env
+~~~~~~~
+
+* ``-e ENV, --env ENV``
+* ``[]``
+
+Set environment variable (key=value).
+
+Pass variables to the execution environment. Ex.::
+
+    $ gunicorn -b 127.0.0.1:8000 --env FOO=1 test:app
+
+and test for the foo variable environment in your application.
+
+.. _pidfile:
+
+pidfile
+~~~~~~~
+
+* ``-p FILE, --pid FILE``
+* ``None``
+
+A filename to use for the PID file.
+
+If not set, no PID file will be written.
+
+.. _worker-tmp-dir:
+
+worker_tmp_dir
+~~~~~~~~~~~~~~
+
+* ``--worker-tmp-dir DIR``
+* ``None``
+
+A directory to use for the worker heartbeat temporary file.
+
+If not set, the default temporary directory will be used.
+
+.. note::
+   The current heartbeat system involves calling ``os.fchmod`` on
+   temporary file handlers and may block a worker for arbitrary time
+   if the directory is on a disk-backed filesystem.
+
+   See :ref:`blocking-os-fchmod` for more detailed information
+   and a solution for avoiding this problem.
+
+.. _user:
+
+user
+~~~~
+
+* ``-u USER, --user USER``
+* ``501``
+
+Switch worker processes to run as this user.
+
+A valid user id (as an integer) or the name of a user that can be
+retrieved with a call to ``pwd.getpwnam(value)`` or ``None`` to not
+change the worker process user.
+
+.. _group:
+
+group
+~~~~~
+
+* ``-g GROUP, --group GROUP``
+* ``20``
+
+Switch worker process to run as this group.
+
+A valid group id (as an integer) or the name of a user that can be
+retrieved with a call to ``pwd.getgrnam(value)`` or ``None`` to not
+change the worker processes group.
+
+.. _umask:
+
+umask
+~~~~~
+
+* ``-m INT, --umask INT``
+* ``0``
+
+A bit mask for the file mode on files written by Gunicorn.
+
+Note that this affects unix socket permissions.
+
+A valid value for the ``os.umask(mode)`` call or a string compatible
+with ``int(value, 0)`` (``0`` means Python guesses the base, so values
+like ``0``, ``0xFF``, ``0022`` are valid for decimal, hex, and octal
+representations)
+
+.. _initgroups:
+
+initgroups
+~~~~~~~~~~
+
+* ``--initgroups``
+* ``False``
+
+If true, set the worker process's group access list with all of the
+groups of which the specified username is a member, plus the specified
+group id.
+
+.. versionadded:: 19.7
+
+.. _tmp-upload-dir:
+
+tmp_upload_dir
+~~~~~~~~~~~~~~
+
+* ``None``
+
+Directory to store temporary request data as they are read.
+
+This may disappear in the near future.
+
+This path should be writable by the process permissions set for Gunicorn
+workers. If not specified, Gunicorn will choose a system generated
+temporary directory.
+
+.. _secure-scheme-headers:
+
+secure_scheme_headers
+~~~~~~~~~~~~~~~~~~~~~
+
+* ``{'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}``
+
+A dictionary containing headers and values that the front-end proxy
+uses to indicate HTTPS requests. These tell Gunicorn to set
+``wsgi.url_scheme`` to ``https``, so your application can tell that the
+request is secure.
+
+The dictionary should map upper-case header names to exact string
+values. The value comparisons are case-sensitive, unlike the header
+names, so make sure they're exactly what your front-end proxy sends
+when handling HTTPS requests.
+
+It is important that your front-end proxy configuration ensures that
+the headers defined here can not be passed directly from the client.
+
+.. _forwarded-allow-ips:
+
+forwarded_allow_ips
+~~~~~~~~~~~~~~~~~~~
+
+* ``--forwarded-allow-ips STRING``
+* ``127.0.0.1``
+
+Front-end's IPs from which allowed to handle set secure headers.
+(comma separate).
+
+Set to ``*`` to disable checking of Front-end IPs (useful for setups
+where you don't know in advance the IP address of Front-end, but
+you still trust the environment).
+
+By default, the value of the ``FORWARDED_ALLOW_IPS`` environment
+variable. If it is not defined, the default is ``"127.0.0.1"``.
+
+.. _pythonpath:
+
+pythonpath
+~~~~~~~~~~
+
+* ``--pythonpath STRING``
+* ``None``
+
+A comma-separated list of directories to add to the Python path.
+
+e.g.
+``'/home/djangoprojects/myproject,/home/python/mylibrary'``.
+
+.. _paste:
+
+paste
+~~~~~
+
+* ``--paste STRING, --paster STRING``
+* ``None``
+
+Load a PasteDeploy config file. The argument may contain a ``#``
+symbol followed by the name of an app section from the config file,
+e.g. ``production.ini#admin``.
+
+At this time, using alternate server blocks is not supported. Use the
+command line arguments to control server configuration instead.
+
+.. _proxy-protocol:
+
+proxy_protocol
+~~~~~~~~~~~~~~
+
+* ``--proxy-protocol``
+* ``False``
+
+Enable detect PROXY protocol (PROXY mode).
+
+Allow using HTTP and Proxy together. It may be useful for work with
+stunnel as HTTPS frontend and Gunicorn as HTTP server.
+
+PROXY protocol: http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
+
+Example for stunnel config::
+
+    [https]
+    protocol = proxy
+    accept  = 443
+    connect = 80
+    cert = /etc/ssl/certs/stunnel.pem
+    key = /etc/ssl/certs/stunnel.key
+
+.. _proxy-allow-ips:
+
+proxy_allow_ips
+~~~~~~~~~~~~~~~
+
+* ``--proxy-allow-from``
+* ``127.0.0.1``
+
+Front-end's IPs from which allowed accept proxy requests (comma separate).
+
+Set to ``*`` to disable checking of Front-end IPs (useful for setups
+where you don't know in advance the IP address of Front-end, but
+you still trust the environment)
+
+.. _raw-paste-global-conf:
+
+raw_paste_global_conf
+~~~~~~~~~~~~~~~~~~~~~
+
+* ``--paste-global CONF``
+* ``[]``
+
+Set a PasteDeploy global config variable in ``key=value`` form.
+
+The option can be specified multiple times.
+
+The variables are passed to the the PasteDeploy entrypoint. Example::
+
+    $ gunicorn -b 127.0.0.1:8000 --paste development.ini --paste-global FOO=1 --paste-global BAR=2
+
+.. versionadded:: 19.7
+
+Server Socket
+-------------
+
+.. _bind:
+
+bind
+~~~~
+
+* ``-b ADDRESS, --bind ADDRESS``
+* ``['127.0.0.1:8000']``
+
+The socket to bind.
+
+A string of the form: ``HOST``, ``HOST:PORT``, ``unix:PATH``. An IP is
+a valid ``HOST``.
+
+Multiple addresses can be bound. ex.::
+
+    $ gunicorn -b 127.0.0.1:8000 -b [::1]:8000 test:app
+
+will bind the `test:app` application on localhost both on ipv6
+and ipv4 interfaces.
+
+.. _backlog:
+
+backlog
+~~~~~~~
+
+* ``--backlog INT``
+* ``2048``
+
+The maximum number of pending connections.
+
+This refers to the number of clients that can be waiting to be served.
+Exceeding this number results in the client getting an error when
+attempting to connect. It should only affect servers under significant
+load.
+
+Must be a positive integer. Generally set in the 64-2048 range.
+
+Worker Processes
+----------------
+
+.. _workers:
+
+workers
+~~~~~~~
+
+* ``-w INT, --workers INT``
+* ``1``
+
+The number of worker processes for handling requests.
+
+A positive integer generally in the ``2-4 x $(NUM_CORES)`` range.
+You'll want to vary this a bit to find the best for your particular
+application's work load.
+
+By default, the value of the ``WEB_CONCURRENCY`` environment variable.
+If it is not defined, the default is ``1``.
+
+.. _worker-class:
+
+worker_class
+~~~~~~~~~~~~
+
+* ``-k STRING, --worker-class STRING``
+* ``sync``
+
+The type of workers to use.
+
+The default class (``sync``) should handle most "normal" types of
+workloads. You'll want to read :doc:`design` for information on when
+you might want to choose one of the other worker classes. Required
+libraries may be installed using setuptools' ``extra_require`` feature.
+
+A string referring to one of the following bundled classes:
+
+* ``sync``
+* ``eventlet`` - Requires eventlet >= 0.9.7 (or install it via 
+  ``pip install gunicorn[eventlet]``)
+* ``gevent``   - Requires gevent >= 0.13 (or install it via 
+  ``pip install gunicorn[gevent]``)
+* ``tornado``  - Requires tornado >= 0.2 (or install it via 
+  ``pip install gunicorn[tornado]``)
+* ``gthread``  - Python 2 requires the futures package to be installed
+  (or install it via ``pip install gunicorn[gthread]``)
+* ``gaiohttp`` - Deprecated.
+
+Optionally, you can provide your own worker by giving Gunicorn a
+Python path to a subclass of ``gunicorn.workers.base.Worker``.
+This alternative syntax will load the gevent class:
+``gunicorn.workers.ggevent.GeventWorker``.
+
+.. deprecated:: 19.8
+   The ``gaiohttp`` worker is deprecated. Please use
+   ``aiohttp.worker.GunicornWebWorker`` instead. See
+   :ref:`asyncio-workers` for more information on how to use it.
+
+.. _threads:
+
+threads
+~~~~~~~
+
+* ``--threads INT``
+* ``1``
+
+The number of worker threads for handling requests.
+
+Run each worker with the specified number of threads.
+
+A positive integer generally in the ``2-4 x $(NUM_CORES)`` range.
+You'll want to vary this a bit to find the best for your particular
+application's work load.
+
+If it is not defined, the default is ``1``.
+
+This setting only affects the Gthread worker type.
+
+.. note::
+   If you try to use the ``sync`` worker type and set the ``threads``
+   setting to more than 1, the ``gthread`` worker type will be used
+   instead.
+
+.. _worker-connections:
+
+worker_connections
+~~~~~~~~~~~~~~~~~~
+
+* ``--worker-connections INT``
+* ``1000``
+
+The maximum number of simultaneous clients.
+
+This setting only affects the Eventlet and Gevent worker types.
+
+.. _max-requests:
+
+max_requests
+~~~~~~~~~~~~
+
+* ``--max-requests INT``
+* ``0``
+
+The maximum number of requests a worker will process before restarting.
+
+Any value greater than zero will limit the number of requests a work
+will process before automatically restarting. This is a simple method
+to help limit the damage of memory leaks.
+
+If this is set to zero (the default) then the automatic worker
+restarts are disabled.
+
+.. _max-requests-jitter:
+
+max_requests_jitter
+~~~~~~~~~~~~~~~~~~~
+
+* ``--max-requests-jitter INT``
+* ``0``
+
+The maximum jitter to add to the *max_requests* setting.
+
+The jitter causes the restart per worker to be randomized by
+``randint(0, max_requests_jitter)``. This is intended to stagger worker
+restarts to avoid all workers restarting at the same time.
+
+.. versionadded:: 19.2
+
+.. _timeout:
+
+timeout
+~~~~~~~
+
+* ``-t INT, --timeout INT``
+* ``30``
+
+Workers silent for more than this many seconds are killed and restarted.
+
+Generally set to thirty seconds. Only set this noticeably higher if
+you're sure of the repercussions for sync workers. For the non sync
+workers it just means that the worker process is still communicating and
+is not tied to the length of time required to handle a single request.
+
+.. _graceful-timeout:
+
+graceful_timeout
+~~~~~~~~~~~~~~~~
+
+* ``--graceful-timeout INT``
+* ``30``
+
+Timeout for graceful workers restart.
+
+After receiving a restart signal, workers have this much time to finish
+serving requests. Workers still alive after the timeout (starting from
+the receipt of the restart signal) are force killed.
+
+.. _keepalive:
+
+keepalive
+~~~~~~~~~
+
+* ``--keep-alive INT``
+* ``2``
+
+The number of seconds to wait for requests on a Keep-Alive connection.
+
+Generally set in the 1-5 seconds range for servers with direct connection
+to the client (e.g. when you don't have separate load balancer). When
+Gunicorn is deployed behind a load balancer, it often makes sense to
+set this to a higher value.
+
+.. note::
+   ``sync`` worker does not support persistent connections and will
+   ignore this option.
+

+ 119 - 0
desktop/core/ext-py/gunicorn-19.9.0/docs/source/signals.rst

@@ -0,0 +1,119 @@
+.. _signals:
+
+===============
+Signal Handling
+===============
+
+A brief description of the signals handled by Gunicorn. We also document the
+signals used internally by Gunicorn to communicate with the workers.
+
+Master process
+==============
+
+- ``QUIT``, ``INT``: Quick shutdown
+- ``TERM``: Graceful shutdown. Waits for workers to finish their
+  current requests up to the :ref:`graceful-timeout`.
+- ``HUP``: Reload the configuration, start the new worker processes with a new
+  configuration and gracefully shutdown older workers. If the application is
+  not preloaded (using the :ref:`preload-app` option), Gunicorn will also load
+  the new version of it.
+- ``TTIN``: Increment the number of processes by one
+- ``TTOU``: Decrement the number of processes by one
+- ``USR1``: Reopen the log files
+- ``USR2``: Upgrade Gunicorn on the fly. A separate ``TERM`` signal should
+  be used to kill the old master process. This signal can also be used to use
+  the new versions of pre-loaded applications. See :ref:`binary-upgrade` for
+  more information.
+- ``WINCH``: Gracefully shutdown the worker processes when Gunicorn is
+  daemonized.
+
+Worker process
+==============
+
+Sending signals directly to the worker processes should not normally be
+needed.  If the master process is running, any exited worker will be
+automatically respawned.
+
+- ``QUIT``, ``INT``: Quick shutdown
+- ``TERM``: Graceful shutdown
+- ``USR1``: Reopen the log files
+
+Reload the configuration
+========================
+
+The ``HUP`` signal can be used to reload the Gunicorn configuration on the
+fly.
+
+::
+
+    2013-06-29 06:26:55 [20682] [INFO] Handling signal: hup
+    2013-06-29 06:26:55 [20682] [INFO] Hang up: Master
+    2013-06-29 06:26:55 [20703] [INFO] Booting worker with pid: 20703
+    2013-06-29 06:26:55 [20702] [INFO] Booting worker with pid: 20702
+    2013-06-29 06:26:55 [20688] [INFO] Worker exiting (pid: 20688)
+    2013-06-29 06:26:55 [20687] [INFO] Worker exiting (pid: 20687)
+    2013-06-29 06:26:55 [20689] [INFO] Worker exiting (pid: 20689)
+    2013-06-29 06:26:55 [20704] [INFO] Booting worker with pid: 20704
+
+
+Sending a ``HUP`` signal will reload the configuration, start the new
+worker processes with a new configuration and gracefully shutdown older
+workers. If the application is not preloaded (using the :ref:`preload-app`
+option), Gunicorn will also load the new version of it.
+
+.. _binary-upgrade:
+
+Upgrading to a new binary on the fly
+====================================
+
+.. versionchanged:: 19.6.0
+   PID file naming format has been changed from ``<name>.pid.oldbin`` to
+   ``<name>.pid.2``.
+
+If you need to replace the Gunicorn binary with a new one (when
+upgrading to a new version or adding/removing server modules), you can
+do it without any service downtime - no incoming requests will be
+lost. Preloaded applications will also be reloaded.
+
+First, replace the old binary with a new one, then send a ``USR2`` signal to
+the current master process. It executes a new binary whose PID file is
+postfixed with ``.2`` (e.g. ``/var/run/gunicorn.pid.2``),
+which in turn starts a new master process and new worker processes::
+
+      PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
+    20844 benoitc   20   0 54808  11m 3352 S   0.0  0.1   0:00.36 gunicorn: master [test:app]
+    20849 benoitc   20   0 54808 9.9m 1500 S   0.0  0.1   0:00.02 gunicorn: worker [test:app]
+    20850 benoitc   20   0 54808 9.9m 1500 S   0.0  0.1   0:00.01 gunicorn: worker [test:app]
+    20851 benoitc   20   0 54808 9.9m 1500 S   0.0  0.1   0:00.01 gunicorn: worker [test:app]
+    20854 benoitc   20   0 55748  12m 3348 S   0.0  0.2   0:00.35 gunicorn: master [test:app]
+    20859 benoitc   20   0 55748  11m 1500 S   0.0  0.1   0:00.01 gunicorn: worker [test:app]
+    20860 benoitc   20   0 55748  11m 1500 S   0.0  0.1   0:00.00 gunicorn: worker [test:app]
+    20861 benoitc   20   0 55748  11m 1500 S   0.0  0.1   0:00.01 gunicorn: worker [test:app]
+
+At this point, two instances of Gunicorn are running, handling the
+incoming requests together. To phase the old instance out, you have to
+send a ``WINCH`` signal to the old master process, and its worker
+processes will start to gracefully shut down.
+
+At this point you can still revert to the old process since it hasn't closed
+its listen sockets yet, by following these steps:
+
+- Send a ``HUP`` signal to the old master process - it will start the worker
+  processes without reloading a configuration file
+- Send a ``TERM`` signal to the new master process to gracefully shut down its
+  worker processes
+- Send a ``QUIT`` signal to the new master process to force it quit
+
+If for some reason the new worker processes do not quit, send a ``KILL`` signal
+to them after the new master process quits, and everything will back to exactly
+as before the upgrade attempt.
+
+If the update is successful and you want to keep the new master process, send a
+``TERM`` signal to the old master process to leave only the new server
+running::
+
+      PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
+    20854 benoitc   20   0 55748  12m 3348 S   0.0  0.2   0:00.45 gunicorn: master [test:app]
+    20859 benoitc   20   0 55748  11m 1500 S   0.0  0.1   0:00.02 gunicorn: worker [test:app]
+    20860 benoitc   20   0 55748  11m 1500 S   0.0  0.1   0:00.02 gunicorn: worker [test:app]
+    20861 benoitc   20   0 55748  11m 1500 S   0.0  0.1   0:00.01 gunicorn: worker [test:app]

+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/alt_spec.py → desktop/core/ext-py/gunicorn-19.9.0/examples/alt_spec.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/bad.py → desktop/core/ext-py/gunicorn-19.9.0/examples/bad.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/boot_fail.py → desktop/core/ext-py/gunicorn-19.9.0/examples/boot_fail.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/echo.py → desktop/core/ext-py/gunicorn-19.9.0/examples/echo.py


+ 6 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/example_config.py → desktop/core/ext-py/gunicorn-19.9.0/examples/example_config.py

@@ -89,6 +89,8 @@ spew = False
 #
 #       True or False
 #
+#   raw_env - Pass environment variables to the execution environment.
+#
 #   pidfile - The path to a pid file to write
 #
 #       A path string or None to not write a pid file.
@@ -121,6 +123,10 @@ spew = False
 #
 
 daemon = False
+raw_env = [
+    'DJANGO_SECRET_KEY=something',
+    'SPAM=eggs',
+]
 pidfile = None
 umask = 0
 user = None

+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/cherryapp.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/cherryapp.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/README → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/README


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/manage.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/manage.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/__init__.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/__init__.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/__init__.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/__init__.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/gunicorn/instrument/__init__.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/__init__.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/middleware.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/middleware.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/models.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/models.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/templates/base.html → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/templates/base.html


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/templates/home.html → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/templates/home.html


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/tests.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/tests.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/urls.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/urls.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/apps/someapp/views.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/apps/someapp/views.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/settings.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/settings.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/urls.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/urls.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/django/testing/testing/wsgi.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/django/testing/testing/wsgi.py


+ 0 - 0
desktop/core/ext-py/gunicorn-19.7.1/examples/frameworks/flask_sendfile.py → desktop/core/ext-py/gunicorn-19.9.0/examples/frameworks/flask_sendfile.py


Някои файлове не бяха показани, защото твърде много файлове са промени