Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of github.com:cherokee/webserver into go-pro-em…

…bedded-cherokee-server--v1.2.101-base

Conflicts:
	cherokee/handler_streaming.c
  • Loading branch information...
commit 5c9e81ad9a15150e645ca4a4b719c7bf4dbfac8f 2 parents 39f0466 + 0c948e5
M. David Peterson mdavid authored
Showing with 27,855 additions and 4,875 deletions.
  1. +0 −3  .gitmodules
  2. +0 −113 README
  3. +210 −0 README.rst
  4. +1 −1  admin/About.py
  5. +1 −1  admin/Auth.py
  6. +1 −1  admin/Balancer.py
  7. +0 −1  admin/CTK
  8. +1 −0  admin/CTK/AUTHORS
  9. +381 −0 admin/CTK/CTK-run.pre
  10. +107 −0 admin/CTK/CTK/AjaxUpload.py
  11. +84 −0 admin/CTK/CTK/Box.py
  12. +65 −0 admin/CTK/CTK/Button.py
  13. +122 −0 admin/CTK/CTK/Carousel.py
  14. +168 −0 admin/CTK/CTK/Checkbox.py
  15. +119 −0 admin/CTK/CTK/Collapsible.py
  16. +134 −0 admin/CTK/CTK/Combobox.py
  17. +484 −0 admin/CTK/CTK/Config.py
  18. +62 −0 admin/CTK/CTK/Container.py
  19. +69 −0 admin/CTK/CTK/DatePicker.py
  20. +273 −0 admin/CTK/CTK/Dialog.py
  21. +240 −0 admin/CTK/CTK/Downloader.py
  22. +311 −0 admin/CTK/CTK/Druid.py
  23. +164 −0 admin/CTK/CTK/HTTP.py
  24. +119 −0 admin/CTK/CTK/Help.py
  25. +50 −0 admin/CTK/CTK/HiddenField.py
  26. +108 −0 admin/CTK/CTK/Image.py
  27. +61 −0 admin/CTK/CTK/Indenter.py
  28. +56 −0 admin/CTK/CTK/Init.py
  29. +87 −0 admin/CTK/CTK/JS.py
  30. +121 −0 admin/CTK/CTK/Link.py
  31. +102 −0 admin/CTK/CTK/List.py
  32. +231 −0 admin/CTK/CTK/MailHTML.py
  33. +62 −0 admin/CTK/CTK/Makefile.am
  34. +79 −0 admin/CTK/CTK/Notice.py
  35. +204 −0 admin/CTK/CTK/Page.py
  36. +56 −0 admin/CTK/CTK/PageCleaner.py
  37. +172 −0 admin/CTK/CTK/Paginator.py
  38. +261 −0 admin/CTK/CTK/Plugin.py
  39. +100 −0 admin/CTK/CTK/Post.py
  40. +66 −0 admin/CTK/CTK/ProgressBar.py
  41. +136 −0 admin/CTK/CTK/PropsTable.py
  42. +90 −0 admin/CTK/CTK/Proxy.py
  43. +101 −0 admin/CTK/CTK/Radio.py
  44. +69 −0 admin/CTK/CTK/RawHTML.py
  45. +179 −0 admin/CTK/CTK/Refreshable.py
  46. +476 −0 admin/CTK/CTK/Server.py
  47. +133 −0 admin/CTK/CTK/SortableList.py
  48. +92 −0 admin/CTK/CTK/StarRating.py
  49. +156 −0 admin/CTK/CTK/Submitter.py
  50. +212 −0 admin/CTK/CTK/Tab.py
  51. +278 −0 admin/CTK/CTK/Table.py
  52. +91 −0 admin/CTK/CTK/Template.py
  53. +57 −0 admin/CTK/CTK/TextArea.py
  54. +252 −0 admin/CTK/CTK/TextField.py
  55. +157 −0 admin/CTK/CTK/ToggleButton.py
  56. +178 −0 admin/CTK/CTK/Uploader.py
  57. +162 −0 admin/CTK/CTK/Widget.py
  58. +86 −0 admin/CTK/CTK/XMLRPCProxy.py
  59. +83 −0 admin/CTK/CTK/__init__.py
  60. +16 −15 admin/{market/__init__.py → CTK/CTK/consts.py}
  61. +110 −0 admin/CTK/CTK/i18n.py
  62. +82 −0 admin/CTK/CTK/iPhoneToggle.py
  63. +548 −0 admin/CTK/CTK/json_embedded.py
  64. +278 −0 admin/CTK/CTK/pyscgi.py
  65. +208 −0 admin/CTK/CTK/util.py
  66. +29 −0 admin/CTK/LICENSE
  67. +6 −0 admin/CTK/MANIFEST.in
  68. +14 −0 admin/CTK/Makefile.am
  69. +58 −0 admin/CTK/README
  70. +13 −0 admin/CTK/setup.py
  71. +3 −0  admin/CTK/static/Makefile.am
  72. +408 −0 admin/CTK/static/css/CTK.css
  73. +11 −0 admin/CTK/static/css/Makefile.am
  74. +59 −0 admin/CTK/static/css/datepicker.css
  75. +406 −0 admin/CTK/static/css/jquery-ui-1.7.2.custom.css
  76. +195 −0 admin/CTK/static/css/jquery.ibutton.css
  77. +42 −0 admin/CTK/static/images/Makefile.am
  78. BIN  admin/CTK/static/images/arrow_ns.png
  79. BIN  admin/CTK/static/images/bg-dialog-buttonpane.png
  80. BIN  admin/CTK/static/images/bg-dialog-titlebar-close.gif
  81. BIN  admin/CTK/static/images/bg-dialog-titlebar.png
  82. BIN  admin/CTK/static/images/bg-dialog.png
  83. BIN  admin/CTK/static/images/bg-filter.png
  84. BIN  admin/CTK/static/images/bg-sel-actions-sel.png
  85. BIN  admin/CTK/static/images/bg-sel-actions.png
  86. BIN  admin/CTK/static/images/carousel-left-arrow.png
  87. BIN  admin/CTK/static/images/carousel-right-arrow.png
  88. BIN  admin/CTK/static/images/del-hover.png
  89. BIN  admin/CTK/static/images/del.png
  90. BIN  admin/CTK/static/images/dialog-error.png
  91. BIN  admin/CTK/static/images/dialog-information.png
  92. BIN  admin/CTK/static/images/dialog-warning.png
  93. BIN  admin/CTK/static/images/forbid.png
  94. BIN  admin/CTK/static/images/ibutton-slider-default.png
  95. BIN  admin/CTK/static/images/input-bg.png
  96. BIN  admin/CTK/static/images/jquery.ui.stars.gif
  97. BIN  admin/CTK/static/images/loader.gif
  98. BIN  admin/CTK/static/images/loading.gif
  99. BIN  admin/CTK/static/images/off.png
  100. BIN  admin/CTK/static/images/offline.png
  101. BIN  admin/CTK/static/images/on.png
  102. BIN  admin/CTK/static/images/online.png
  103. BIN  admin/CTK/static/images/tabbg.png
  104. BIN  admin/CTK/static/images/tick.png
  105. BIN  admin/CTK/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png
  106. BIN  admin/CTK/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
  107. BIN  admin/CTK/static/images/ui-icons_222222_256x240.png
  108. BIN  admin/CTK/static/images/ui-icons_2e83ff_256x240.png
  109. BIN  admin/CTK/static/images/ui-icons_454545_256x240.png
  110. BIN  admin/CTK/static/images/ui-icons_888888_256x240.png
  111. BIN  admin/CTK/static/images/ui-icons_cd0a0a_256x240.png
  112. BIN  admin/CTK/static/images/uploadify.cancel.png
  113. +101 −0 admin/CTK/static/js/Carousel.js
  114. +72 −0 admin/CTK/static/js/Help.js
  115. +22 −0 admin/CTK/static/js/Makefile.am
  116. +115 −0 admin/CTK/static/js/StarRating.js
  117. +248 −0 admin/CTK/static/js/Submitter.js
  118. +564 −0 admin/CTK/static/js/ajaxupload.3.6.js
  119. +47 −0 admin/CTK/static/js/common.js
  120. +4,376 −0 admin/CTK/static/js/jquery-1.3.2.js
  121. +19 −0 admin/CTK/static/js/jquery-1.3.2.min.js
  122. +298 −0 admin/CTK/static/js/jquery-ui-1.7.2.custom.min.js
  123. +9,237 −0 admin/CTK/static/js/jquery-ui-1.7.2.js
  124. +96 −0 admin/CTK/static/js/jquery.cookie.js
  125. +53 −0 admin/CTK/static/js/jquery.form-defaults.js
  126. +383 −0 admin/CTK/static/js/jquery.ibutton.js
  127. +374 −0 admin/CTK/static/js/jquery.tablednd_0_5.js
  128. +116 −0 admin/CTK/static/js/jquery.uploadProgress.js
  129. +305 −0 admin/CTK/tests/cherokee.conf.orig
  130. +65 −0 admin/CTK/tests/druid-submits.py
  131. +50 −0 admin/CTK/tests/run.py
  132. +51 −0 admin/CTK/tests/test1.py
  133. +59 −0 admin/CTK/tests/test11.py
  134. +32 −0 admin/CTK/tests/test14.py
  135. +19 −0 admin/CTK/tests/test15.py
  136. +13 −0 admin/CTK/tests/test16.py
  137. +78 −0 admin/CTK/tests/test19.py
  138. +27 −0 admin/CTK/tests/test1_env.py
  139. +57 −0 admin/CTK/tests/test2-login.py
  140. +24 −0 admin/CTK/tests/test22.py
  141. +43 −0 admin/CTK/tests/test2_post.py
  142. +35 −0 admin/CTK/tests/test3.py
  143. +27 −0 admin/CTK/tests/test5.py
  144. +56 −0 admin/CTK/tests/test6.py
  145. +23 −0 admin/CTK/tests/test7.py
  146. +1 −1  admin/Certs.py
  147. +1 −1  admin/CgiBase.py
  148. +1 −1  admin/Cherokee.py
  149. +1 −1  admin/Flags.py
  150. +1 −1  admin/Graph.py
  151. +1 −1  admin/Handler.py
  152. +1 −1  admin/Icons.py
  153. +1 −5 admin/Makefile.am
  154. +1 −1  admin/Mime.py
  155. +0 −340 admin/OWS_Backup.py
  156. +0 −136 admin/OWS_Cherokee_Info.py
  157. +0 −136 admin/OWS_Login.py
  158. +0 −110 admin/OWS_Market_Info.py
  159. +1 −2  admin/Page.py
  160. +1 −15 admin/PageAdvanced.py
  161. +6 −6 admin/PageEntry.py
  162. +1 −54 admin/PageError.py
  163. +1 −1  admin/PageException.py
  164. +101 −5 admin/PageGeneral.py
  165. +1 −1  admin/PageHelp.py
  166. +11 −160 admin/PageIndex.py
  167. +1 −1  admin/PageNewConfig.py
  168. +1 −1  admin/PageRule.py
  169. +1 −1  admin/PageSource.py
  170. +1 −1  admin/PageSources.py
  171. +1 −1  admin/PageStatus.py
  172. +8 −8 admin/PageVServer.py
  173. +3 −26 admin/PageVServers.py
  174. +1 −1  admin/Rule.py
  175. +1 −1  admin/RuleSimple.py
  176. +1 −1  admin/SaveButton.py
  177. +1 −1  admin/SavingChecks.py
  178. +1 −1  admin/SelectionPanel.py
  179. +1 −1  admin/SystemInfo.py
  180. +1 −1  admin/SystemStats.py
  181. +1 −1  admin/SystemStatsWidgets.py
  182. +1 −1  admin/Wizard.py
  183. +1 −1  admin/XMLServerDigest.py
  184. +47 −0 admin/config_version.py
  185. +0 −4 admin/configured.py.pre
  186. +1 −1  admin/consts.py
  187. +0 −266 admin/market/CommandProgress.py
  188. +0 −167 admin/market/Distro.py
  189. +0 −531 admin/market/Install.py
  190. +0 −96 admin/market/InstallUtil.py
  191. +0 −72 admin/market/Install_Log.py
  192. +0 −106 admin/market/Library.py
  193. +0 −595 admin/market/Maintenance.py
  194. +0 −27 admin/market/Makefile.am
  195. +0 −55 admin/market/Menu.py
  196. +0 −218 admin/market/PageApp.py
  197. +0 −96 admin/market/PageCategory.py
  198. +0 −155 admin/market/PageIndex.py
  199. +0 −97 admin/market/PageSearch.py
  200. +0 −144 admin/market/Report.py
  201. +0 −98 admin/market/Review.py
  202. +0 −245 admin/market/Util.py
  203. +0 −44 admin/market/ows_consts.py
  204. +1 −1  admin/plugins/admin.py
  205. +1 −1  admin/plugins/authlist.py
  206. +1 −1  admin/plugins/bind.py
  207. +1 −1  admin/plugins/cgi.py
  208. +1 −1  admin/plugins/common.py
  209. +1 −1  admin/plugins/custom_error.py
  210. +1 −1  admin/plugins/dbslayer.py
  211. +1 −1  admin/plugins/deflate.py
  212. +1 −1  admin/plugins/directory.py
  213. +2 −2 admin/plugins/dirlist.py
  214. +1 −1  admin/plugins/drop.py
  215. +1 −1  admin/plugins/empty_gif.py
  216. +1 −1  admin/plugins/error_nn.py
  217. +1 −1  admin/plugins/error_redir.py
  218. +1 −1  admin/plugins/evhost.py
  219. +1 −1  admin/plugins/exists.py
  220. +1 −1  admin/plugins/extensions.py
  221. +1 −1  admin/plugins/failover.py
  222. +1 −1  admin/plugins/fcgi.py
  223. +1 −1  admin/plugins/file.py
  224. +1 −1  admin/plugins/from.py
  225. +1 −1  admin/plugins/fullpath.py
  226. +1 −1  admin/plugins/geoip.py
  227. +1 −1  admin/plugins/gzip.py
  228. +1 −1  admin/plugins/header.py
  229. +1 −1  admin/plugins/htdigest.py
  230. +1 −1  admin/plugins/htpasswd.py
  231. +1 −1  admin/plugins/ip_hash.py
  232. +1 −1  admin/plugins/ldap.py
  233. +3 −3 admin/plugins/method.py
  234. +2 −2 admin/plugins/mysql.py
  235. +1 −1  admin/plugins/pam.py
  236. +1 −1  admin/plugins/plain.py
  237. +1 −1  admin/plugins/post_report.py
  238. +1 −1  admin/plugins/post_track.py
  239. +1 −1  admin/plugins/proxy.py
  240. +1 −1  admin/plugins/redir.py
  241. +1 −1  admin/plugins/rehost.py
  242. +1 −1  admin/plugins/request.py
  243. +1 −1  admin/plugins/round_robin.py
  244. +1 −1  admin/plugins/rrd.py
  245. +1 −1  admin/plugins/scgi.py
  246. +1 −1  admin/plugins/secdownload.py
  247. +1 −1  admin/plugins/server_info.py
  248. +1 −1  admin/plugins/ssi.py
  249. +1 −1  admin/plugins/streaming.py
  250. +1 −1  admin/plugins/target_ip.py
  251. +1 −1  admin/plugins/tls.py
  252. +1 −1  admin/plugins/url_arg.py
  253. +1 −1  admin/plugins/uwsgi.py
  254. +1 −1  admin/plugins/wildcard.py
  255. +1 −1  admin/popen.py
  256. +2 −47 admin/server.py
  257. +1 −462 admin/static/css/cherokee-admin.css
  258. +0 −2  admin/static/images/Makefile.am
  259. BIN  admin/static/images/market.png
  260. +2 −0  admin/static/images/other/Makefile.am
  261. BIN  admin/static/images/other/github.png
  262. BIN  admin/static/images/other/googleplus.png
  263. BIN  admin/static/images/sidebar-market.png
  264. +1 −1  admin/static/js/SelectionPanel.js
  265. +0 −1  admin/theme.html
  266. +2 −2 admin/upgrade_config.py
  267. +1 −1  admin/util.py
  268. +2 −2 admin/wizards/List.py
  269. +1 −1  admin/wizards/alfresco.py
  270. +1 −1  admin/wizards/coldfusion.py
  271. +1 −1  admin/wizards/concrete5.py
  272. +7 −5 admin/wizards/django.py
  273. +1 −1  admin/wizards/flcache.py
  274. +1 −1  admin/wizards/glassfish.py
  275. +1 −1  admin/wizards/hotlinking.py
  276. +5 −5 admin/wizards/icons.py
  277. +1 −1  admin/wizards/mailman.py
  278. +1 −1  admin/wizards/mono.py
  279. +38 −4 admin/wizards/php.py
  280. +3 −7 admin/wizards/rails.py
  281. +1 −1  admin/wizards/redirect.py
  282. +1 −1  admin/wizards/rtorrent.py
  283. +1 −1  admin/wizards/ssl_test.py
  284. +1 −1  admin/wizards/static.py
  285. +1 −1  admin/wizards/streaming.py
  286. +1 −1  admin/wizards/symfony.py
  287. +1 −1  admin/wizards/uwsgi.py
  288. +1 −1  admin/wizards/zend.py
  289. +4 −3 autogen.sh
  290. +1 −1  cget/Makefile.am
  291. +2 −2 cget/main.c
  292. +1 −1  cget/proxy.c
  293. +1 −1  cget/proxy.h
  294. +1 −1  cherokee.conf.sample.pre
  295. +1 −1  cherokee.spec.in
  296. +7 −70 cherokee/Makefile.am
  297. +1 −1  cherokee/access.c
  298. +1 −1  cherokee/access.h
  299. +1 −1  cherokee/admin_request.c
  300. +1 −1  cherokee/admin_request.h
Sorry, we could not display the entire diff because too many files (664) changed.
3  .gitmodules
View
@@ -1,3 +0,0 @@
-[submodule "admin/CTK"]
- path = admin/CTK
- url = git://github.com/cherokee/CTK.git
113 README
View
@@ -1,113 +0,0 @@
-Cherokee Web Server
-===================
-
-Web site
---------
- http://www.cherokee-project.com/
-
-
-License
--------
- Cherokee is released under GPL v2. Read the COPYING file for more
- information.
-
-
-Mailing lists
--------------
- There are a few mailing lists available. Please, do not hesitate to
- subscribe to any on them:
-
- http://lists.cherokee-project.com/
-
- This is the main mailing list, where questions are sent and general
- discussion takes place.
-
- There are also a few technical mailing lists. Developers and package
- maintainers usually subscribe to these mailing lists as well:
-
- http://lists.cherokee-project.com/listinfo/cherokee-dev
- http://lists.cherokee-project.com/listinfo/cherokee-commits
-
- The mailing lists' archives are available at:
-
- http://lists.cherokee-project.com/pipermail/cherokee/
-
-
-IRC channel
------------
- irc.freenode.net, channel #cherokee
-
-
-Building from a tar.gz file
----------------------------
- Run ./configure, with some options if you wish. The standard options
- are documented in the INSTALL file. The only interesting ones are
- the usual --prefix=/usr, --localstatedir=/var and --sysconfdir=/etc
-
- Do "make", and then do "make install" (possibly as root if the
- destination permissions require that).
-
- That's all.
-
-
-Building from the repository
-----------------------------
- Check out the code from SVN, following the instructions at:
-
- http://svn.cherokee-project.com/
-
- cd into the source directory and run ./autogen.sh to setup the
- environment (you need the standard autoconf tools to do so).
-
- Then, continue with the following instructions...
-
-
-FAQ
----
- Here is a list of the most frequently asked questions:
-
- How to compile it
- ------------------
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
- make
-
- How to create dynamic modules
- -----------------------------
- It's the default way.
-
- How to configure the module xyz to be linked statically
- -------------------------------------------------------
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=xyz
-
- How to build everyhing statically
- ---------------------------------
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=all
-
- How to create a self signed certificate for TLS
- -----------------------------------------------
- openssl req -days 1000 -new -x509 -nodes -out /etc/cherokee/ssl/cherokee.pem -keyout /etc/cherokee/ssl/cherokee.pem
-
- How to compile it on Windows
- ----------------------------
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=all --enable-static --enable-shared=no --enable-beta --enable-trace
-
- How to build a MacOS X binary package
- -----------------------------------
- ./autogen.sh --prefix=/usr/local --with-wwwroot=/Library/WebServer/Documents --with-wwwuser=www --with-wwwgroup=www --with-mysql=no --with-ffmpeg=no --with-ldap=no --enable-beta
- make -j8
- packages/osx/build.py
-
- Development
- -----------
- ./autogen.sh --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=all --enable-static --enable-shared=no --with-mysql=no --with-ffmpeg=no --with-ldap=no --enable-beta --enable-trace --enable-backtraces --enable-maintainer-mode
- make CFLAGS="-ggdb3 -O0" -j8
-
- How to cross compile the Win32 version
- --------------------------------------
- From Linux: http://alobbs.com/news/1201
- From MacOS: http://alobbs.com/news/1299
- From Win32: http://unixwars.com/2008/07/17/c/
-
---
-Alvaro Lopez Ortega
-alvaro@alobbs.com
210 README.rst
View
@@ -0,0 +1,210 @@
+Cherokee Web Server
+===================
+
+Web site
+--------
+
+Visit our main website for the latest updates: http://www.cherokee-project.com/
+
+Compiling from source
+---------------------
+
+Building from the repository
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To build from the repository, you will require ``autoconf``, ``automake``, and
+``libtool`` tools to be available, typically available on your distribution
+either by default or by running the following on Debian-based systems::
+
+ sudo apt-get install autoconf automake libtool
+
+or, for Yum-based systems, such as RedHat, CentOS or Fedora::
+
+ sudo yum install autoconf automake libtool
+
+or, for Pacman-based systems such as ArchLinux::
+
+ sudo pacman -Sy autoconf automake libtool
+
+To check out the code from GitHub, including all dependencies that are
+specified as Git submodules, do the following::
+
+ git clone --recursive http://github.com/cherokee/webserver.git
+
+or, if using a version of Git < 1.6.5, run::
+
+ git clone http://github.com/cherokee/webserver.git
+ git submodule update --init
+
+Once cloned, ``cd`` into the resulting source directory and run
+``./autogen.sh`` to set up the environment and generate ``./configure``::
+
+ cd webserver
+ ./autogen.sh [options]
+ make
+ make install
+
+``./autogen.sh`` will accept any optional parameters otherwise typically passed
+to ``./configure``; in doing so you can avoid needing to run ``./configure``
+separately.
+
+Several examples of using ``./autogen.sh`` follow shortly in the
+`Frequently Asked Questions (FAQ)`_ section.
+
+Building from a tar.gz file
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+After downloading (likely from http://www.cherokee-project.com/downloads.html)
+and extracting, you should run ``./configure``, with options as appropriate.
+The standard options are documented in the ``INSTALL`` file. Typically,
+the most interesting options are:
+
+* the usual ``--prefix=/usr``
+* ``--localstatedir=/var``
+* ``--sysconfdir=/etc``
+
+After running ``./configure``, issues the ``make`` command, and then ``make
+install`` (excuting this last command as root if the destination permissions
+require that).
+
+Tying this all together will result in commands like the following::
+
+ wget http://www.cherokee-project.com/download/trunk/cherokee-latest-snapshot.tar.gz
+ tar xf cherokee-latest-snapshot.tar.gz
+ cd cherokee-latest-snapshot
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
+ make
+ sudo make install
+
+The exact options passed to ``./configure`` can vary based upon your
+configuration.
+
+
+License
+-------
+
+Cherokee is released under GPL v2. Read the ``COPYING`` file for more
+information.
+
+
+Mailing lists
+-------------
+
+There are several mailing lists available for Cherokee and they are listed
+at:
+
+ http://lists.cherokee-project.com/
+
+The main mailing list, where questions should be sent and general
+discussion takes place, is:
+
+ http://lists.cherokee-project.com/listinfo/cherokee
+
+There are also a few technical mailing lists. Developers and package
+maintainers should subscribe to these mailing lists as well as the main mailing
+list:
+
+ http://lists.cherokee-project.com/listinfo/cherokee-dev
+
+ http://lists.cherokee-project.com/listinfo/cherokee-commits
+
+The mailing lists' archives are available at:
+
+ http://lists.cherokee-project.com/pipermail/cherokee/
+
+Don't hesitate to subscribe and contribute to any of the mailing lists!
+
+
+IRC channel
+-----------
+
+Communicate with the Cherokee community via `IRC
+<irc://irc.freenode.net/#cherokee>`_:
+
+ irc.freenode.net, channel #cherokee
+
+
+Frequently Asked Questions (FAQ)
+--------------------------------
+
+Here is a list of the most frequently asked questions regarding
+compilation and similar topics:
+
+How to compile it
+^^^^^^^^^^^^^^^^^
+
+::
+
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
+ make
+
+How to create dynamic modules
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Modules are created dynamically by default.
+
+How to configure the module xyz to be linked statically
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=xyz
+
+How to build everyhing statically
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=all
+
+
+How to compile it on Windows
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=all --enable-static --enable-shared=no --enable-beta --enable-trace
+
+How to build a MacOS X binary package
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ ./autogen.sh --prefix=/usr/local --with-wwwroot=/Library/WebServer/Documents --with-wwwuser=www --with-wwwgroup=www --with-mysql=no --with-ffmpeg=no --with-ldap=no --enable-beta
+ make -j8
+ packages/osx/build.py
+
+Development
+^^^^^^^^^^^
+
+::
+
+ ./autogen.sh --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-static-module=all --enable-static --enable-shared=no --with-mysql=no --with-ffmpeg=no --with-ldap=no --enable-beta --enable-trace --enable-backtraces --enable-maintainer-mode
+ make CFLAGS="-ggdb3 -O0" -j8
+
+How to cross compile the Win32 version
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* From Linux: http://alobbs.com/news/1201
+* From MacOS: http://alobbs.com/news/1299
+* From Win32: http://unixwars.com/2008/07/17/c/
+
+How to create a self signed certificate for TLS
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ openssl req -days 1000 -new -x509 -nodes -out /etc/cherokee/ssl/cherokee.pem -keyout /etc/cherokee/ssl/cherokee.pem
+
+How to create a release .tar.gz
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ git clone --recursive http://github.com/cherokee/webserver.git
+ cd webserver
+ ./autogen.sh
+ make dist-gzip
+
+The resulting file will be created in the current directory and will be
+a ``.tar.gz`` archive.
2  admin/About.py
View
@@ -5,7 +5,7 @@
# Authors:
# Alvaro Lopez Ortega <alvaro@alobbs.com>
#
-# Copyright (C) 2001-2011 Alvaro Lopez Ortega
+# Copyright (C) 2001-2013 Alvaro Lopez Ortega
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
2  admin/Auth.py
View
@@ -5,7 +5,7 @@
# Authors:
# Alvaro Lopez Ortega <alvaro@alobbs.com>
#
-# Copyright (C) 2010 Alvaro Lopez Ortega
+# Copyright (C) 2001-2013 Alvaro Lopez Ortega
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
2  admin/Balancer.py
View
@@ -5,7 +5,7 @@
# Authors:
# Alvaro Lopez Ortega <alvaro@alobbs.com>
#
-# Copyright (C) 2010 Alvaro Lopez Ortega
+# Copyright (C) 2001-2013 Alvaro Lopez Ortega
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
1  admin/CTK
@@ -1 +0,0 @@
-Subproject commit 49e0d36ea4e5ff912fd33ccd138f241a5105c351
1  admin/CTK/AUTHORS
View
@@ -0,0 +1 @@
+Alvaro Lopez Ortega <alvaro@alobbs.com>
381 admin/CTK/CTK-run.pre
View
@@ -0,0 +1,381 @@
+#!/usr/bin/env python
+# -*- Mode: python; coding: utf-8 -*-
+
+import os
+import sys
+import tempfile
+
+DFAULT_SCGI_PORT = 8000
+CTK_ROOT_DEFAULT = "%datadir%/cherokee/admin/CTK"
+
+def write_cherokee_conf (app_file, CTK_root, SCGI_port):
+ # Path to the CTK app
+ if app_file.startswith ('/'):
+ app_file_path = app_file
+ else:
+ app_file_path = os.path.join (os.getcwd(), app_file)
+
+ # Get python executable, to make CTK work in virtualenv for example
+ python_executable = sys.executable
+ # Write the custom configuration file
+ config = CONFIG_BASE[:]
+ config = config.replace ('vserver!10!document_root = /var/www',
+ 'vserver!10!document_root = %s' %(CTK_root))
+ config = config.replace ('source!1!interpreter = /usr/bin/true',
+ 'source!1!interpreter = %s %s' %(python_executable, app_file_path))
+ config = config.replace ('source!1!host = localhost:8000',
+ 'source!1!host = localhost:%s' %(SCGI_port))
+ config = config.replace ('vserver!10!rule!200!document_root = /var/www/static',
+ 'vserver!10!rule!200!document_root = %s/static' %(CTK_root))
+
+ tempfd, tempname = tempfile.mkstemp()
+ os.write(tempfd, config)
+ os.close(tempfd)
+
+ # Set environment var PYTHONPATH
+ os.putenv("PYTHONPATH", "%s:%s"%(CTK_root, os.getenv("PYTHONPATH", '')))
+ return tempname
+
+def main():
+ # Usage
+ if len(sys.argv) < 2:
+ print "USAGE:"
+ print " %s [-d /path/to/CTK] [-s SCGI-port-num] <file.py>" %(sys.argv[0])
+ raise SystemExit
+
+ # Path to CTK
+ if '-d' in sys.argv:
+ CTK_root = sys.argv[sys.argv.index('-d') + 1]
+ else:
+ CTK_root = CTK_ROOT_DEFAULT
+
+ # Internal SCGI port
+ if '-s' in sys.argv:
+ SCGI_port = sys.argv[sys.argv.index('-s') + 1]
+ else:
+ SCGI_port = DFAULT_SCGI_PORT
+
+ # Write config file
+ app_file = filter (lambda x: x.endswith('.py'), sys.argv)[-1]
+ cherokee_conf = write_cherokee_conf (app_file, CTK_root, SCGI_port)
+ command = "cherokee -C %s" %(cherokee_conf)
+
+ # Run
+ print "Running: %s" % (app_file)
+ print "CTK Path: %s" % (CTK_root)
+ print "Executing: %s" % (command)
+ print
+
+ os.system (command)
+
+
+CONFIG_BASE = """\
+config!version = 000099040
+server!bind!1!port = 9091
+server!bind!1!tls = 0
+server!chunked_encoding = 1
+server!iocache = 0
+server!ipv6 = 1
+server!keepalive = 1
+server!keepalive_max_requests = 500
+server!panic_action = /usr/bin/cherokee-panic
+server!post_track = post_track
+server!server_tokens = full
+server!timeout = 15
+vserver!10!collect_statistics = 0
+vserver!10!collector!enabled = 0
+vserver!10!directory_index = index.html
+vserver!10!document_root = /var/www
+vserver!10!error_writer!type = stderr
+vserver!10!keepalive = 1
+vserver!10!logger!x_real_ip_access_all = 0
+vserver!10!logger!x_real_ip_enabled = 0
+vserver!10!nick = default
+vserver!10!rule!400!handler = post_report
+vserver!10!rule!400!match = directory
+vserver!10!rule!400!match!directory = /upload_report
+vserver!10!rule!300!expiration = time
+vserver!10!rule!300!expiration!time = 1h
+vserver!10!rule!300!handler = file
+vserver!10!rule!300!handler!iocache = 0
+vserver!10!rule!300!match = fullpath
+vserver!10!rule!300!match!final = 1
+vserver!10!rule!300!match!fullpath!1 = /favicon.ico
+vserver!10!rule!300!match!fullpath!2 = /robots.txt
+vserver!10!rule!300!match!fullpath!3 = /crossdomain.xml
+vserver!10!rule!200!handler = file
+vserver!10!rule!200!match = directory
+vserver!10!rule!200!match!directory = /CTK
+vserver!10!rule!200!document_root = /var/www/static
+vserver!10!rule!200!match!final = 1
+vserver!10!rule!100!handler = scgi
+vserver!10!rule!100!handler!balancer = round_robin
+vserver!10!rule!100!handler!balancer!source!1 = 1
+vserver!10!rule!100!handler!iocache = 0
+vserver!10!rule!100!handler!xsendfile = 1
+vserver!10!rule!100!match = default
+vserver!10!rule!100!match!final = 1
+source!1!debug = 1
+source!1!env_inherited = 1
+source!1!host = localhost:8000
+source!1!interpreter = /usr/bin/true
+source!1!nick = CTK-run Source
+source!1!type = interpreter
+icons!default = page_white.png
+icons!directory = folder.png
+icons!file!bomb.png = core
+icons!file!page_white_go.png = *README*
+icons!parent_directory = arrow_turn_left.png
+icons!suffix!camera.png = jpg,jpeg,jpe
+icons!suffix!cd.png = iso,ngr,cue
+icons!suffix!color_wheel.png = png,gif,xcf,bmp,pcx,tiff,tif,cdr,psd,xpm,xbm
+icons!suffix!control_play.png = bin,exe,com,msi,out
+icons!suffix!css.png = css
+icons!suffix!cup.png = java,class,jar
+icons!suffix!email.png = eml,mbox,box,email,mbx
+icons!suffix!film.png = avi,mpeg,mpe,mpg,mpeg3,dl,fli,qt,mov,movie,flv
+icons!suffix!font.png = ttf
+icons!suffix!html.png = html,htm
+icons!suffix!music.png = au,snd,mid,midi,kar,mpga,mpega,mp2,mp3,sid,wav,aif,aiff,aifc,gsm,m3u,wma,wax,ra,rm,ram,pls,sd2,ogg
+icons!suffix!package.png = tar,gz,bz2,zip,rar,ace,lha,Z,7z
+icons!suffix!page_white_acrobat.png = pdf
+icons!suffix!page_white_c.png = c,h,cpp
+icons!suffix!page_white_office.png = doc,ppt,xls
+icons!suffix!page_white_php.png = php
+icons!suffix!page_white_text.png = txt,text,rtf,sdw
+icons!suffix!printer.png = ps,eps
+icons!suffix!ruby.png = rb
+icons!suffix!script.png = sh,csh,ksh,tcl,tk,py,pl
+mime!application/bzip2!extensions = bz2
+mime!application/gzip!extensions = gz
+mime!application/hta!extensions = hta
+mime!application/java-archive!extensions = jar
+mime!application/java-serialized-object!extensions = ser
+mime!application/java-vm!extensions = class
+mime!application/json!extensions = json
+mime!application/mac-binhex40!extensions = hqx
+mime!application/msaccess!extensions = mdb
+mime!application/msword!extensions = doc,dot
+mime!application/octet-stream!extensions = bin
+mime!application/octetstream!extensions = ace
+mime!application/oda!extensions = oda
+mime!application/ogg!extensions = ogx
+mime!application/pdf!extensions = pdf
+mime!application/pgp-keys!extensions = key
+mime!application/pgp-signature!extensions = pgp
+mime!application/pics-rules!extensions = prf
+mime!application/postscript!extensions = ps,ai,eps
+mime!application/rar!extensions = rar
+mime!application/rdf+xml!extensions = rdf
+mime!application/rss+xml!extensions = rss
+mime!application/smil!extensions = smi,smil
+mime!application/vnd.mozilla.xul+xml!extensions = xul
+mime!application/vnd.ms-excel!extensions = xls,xlb,xlt
+mime!application/vnd.ms-pki.seccat!extensions = cat
+mime!application/vnd.ms-pki.stl!extensions = stl
+mime!application/vnd.ms-powerpoint!extensions = ppt,pps
+mime!application/vnd.oasis.opendocument.chart!extensions = odc
+mime!application/vnd.oasis.opendocument.database!extensions = odb
+mime!application/vnd.oasis.opendocument.formula!extensions = odf
+mime!application/vnd.oasis.opendocument.graphics!extensions = odg
+mime!application/vnd.oasis.opendocument.image!extensions = odi
+mime!application/vnd.oasis.opendocument.presentation!extensions = odp
+mime!application/vnd.oasis.opendocument.spreadsheet!extensions = ods
+mime!application/vnd.oasis.opendocument.text!extensions = odt
+mime!application/vnd.oasis.opendocument.text-master!extensions = odm
+mime!application/vnd.oasis.opendocument.text-web!extensions = oth
+mime!application/vnd.pkg5.info!extensions = p5i
+mime!application/vnd.visio!extensions = vsd
+mime!application/vnd.wap.wbxml!extensions = wbxml
+mime!application/vnd.wap.wmlc!extensions = wmlc
+mime!application/vnd.wap.wmlscriptc!extensions = wmlsc
+mime!application/x-abiword!extensions = abw
+mime!application/x-apple-diskimage!extensions = dmg
+mime!application/x-bcpio!extensions = bcpio
+mime!application/x-bittorrent!extensions = torrent
+mime!application/x-cdf!extensions = cdf
+mime!application/x-cpio!extensions = cpio
+mime!application/x-csh!extensions = csh
+mime!application/x-debian-package!extensions = deb,udeb
+mime!application/x-director!extensions = dcr,dir,dxr
+mime!application/x-dvi!extensions = dvi
+mime!application/x-flac!extensions = flac
+mime!application/x-font!extensions = pfa,pfb,gsf,pcf,pcf.Z
+mime!application/x-freemind!extensions = mm
+mime!application/x-gnumeric!extensions = gnumeric
+mime!application/x-gtar!extensions = gtar,tgz,taz
+mime!application/x-gzip!extensions = gz,tgz
+mime!application/x-httpd-php!extensions = phtml,pht,php
+mime!application/x-httpd-php-source!extensions = phps
+mime!application/x-httpd-php3!extensions = php3
+mime!application/x-httpd-php3-preprocessed!extensions = php3p
+mime!application/x-httpd-php4!extensions = php4
+mime!application/x-internet-signup!extensions = ins,isp
+mime!application/x-iphone!extensions = iii
+mime!application/x-iso9660-image!extensions = iso
+mime!application/x-java-jnlp-file!extensions = jnlp
+mime!application/x-javascript!extensions = js
+mime!application/x-kchart!extensions = chrt
+mime!application/x-killustrator!extensions = kil
+mime!application/x-koan!extensions = skp,skd,skt,skm
+mime!application/x-kpresenter!extensions = kpr,kpt
+mime!application/x-kspread!extensions = ksp
+mime!application/x-kword!extensions = kwd,kwt
+mime!application/x-latex!extensions = latex
+mime!application/x-lha!extensions = lha
+mime!application/x-lzh!extensions = lzh
+mime!application/x-lzx!extensions = lzx
+mime!application/x-ms-wmd!extensions = wmd
+mime!application/x-ms-wmz!extensions = wmz
+mime!application/x-msdos-program!extensions = com,exe,bat,dll
+mime!application/x-msi!extensions = msi
+mime!application/x-netcdf!extensions = nc
+mime!application/x-ns-proxy-autoconfig!extensions = pac
+mime!application/x-nwc!extensions = nwc
+mime!application/x-object!extensions = o
+mime!application/x-oz-application!extensions = oza
+mime!application/x-pkcs7-certreqresp!extensions = p7r
+mime!application/x-pkcs7-crl!extensions = crl
+mime!application/x-python-code!extensions = pyc,pyo
+mime!application/x-quicktimeplayer!extensions = qtl
+mime!application/x-redhat-package-manager!extensions = rpm
+mime!application/x-sh!extensions = sh
+mime!application/x-shar!extensions = shar
+mime!application/x-shockwave-flash!extensions = swf,swfl
+mime!application/x-stuffit!extensions = sit,sea
+mime!application/x-sv4cpio!extensions = sv4cpio
+mime!application/x-sv4crc!extensions = sv4crc
+mime!application/x-tar!extensions = tar
+mime!application/x-tcl!extensions = tcl
+mime!application/x-tex-pk!extensions = pk
+mime!application/x-texinfo!extensions = texinfo,texi
+mime!application/x-trash!extensions = ~,bak,old,sik
+mime!application/x-troff!extensions = t,tr,roff
+mime!application/x-troff-man!extensions = man
+mime!application/x-troff-me!extensions = me
+mime!application/x-troff-ms!extensions = ms
+mime!application/x-ustar!extensions = ustar
+mime!application/x-x509-ca-cert!extensions = crt
+mime!application/x-xcf!extensions = xcf
+mime!application/x-xfig!extensions = fig
+mime!application/x-xpinstall!extensions = xpi
+mime!application/xhtml+xml!extensions = xhtml,xht
+mime!application/xml!extensions = xml,xsl
+mime!application/zip!extensions = zip
+mime!audio/basic!extensions = au,snd
+mime!audio/midi!extensions = mid,midi,kar
+mime!audio/mpeg!extensions = mpga,mpega,mp2,mp3,m4a
+mime!audio/ogg!extensions = ogg,oga
+mime!audio/prs.sid!extensions = sid
+mime!audio/x-aiff!extensions = aif,aiff,aifc
+mime!audio/x-gsm!extensions = gsm
+mime!audio/x-mpegurl!extensions = m3u
+mime!audio/x-ms-wax!extensions = wax
+mime!audio/x-ms-wma!extensions = wma
+mime!audio/x-pn-realaudio!extensions = ra,rm,ram
+mime!audio/x-realaudio!extensions = ra
+mime!audio/x-scpls!extensions = pls
+mime!audio/x-sd2!extensions = sd2
+mime!audio/x-wav!extensions = wav
+mime!chemical/x-cache!extensions = cac,cache
+mime!chemical/x-cache-csf!extensions = csf
+mime!chemical/x-cdx!extensions = cdx
+mime!chemical/x-cif!extensions = cif
+mime!chemical/x-cmdf!extensions = cmdf
+mime!chemical/x-cml!extensions = cml
+mime!chemical/x-compass!extensions = cpa
+mime!chemical/x-crossfire!extensions = bsd
+mime!chemical/x-csml!extensions = csml,csm
+mime!chemical/x-ctx!extensions = ctx
+mime!chemical/x-cxf!extensions = cxf,cef
+mime!chemical/x-isostar!extensions = istr,ist
+mime!chemical/x-jcamp-dx!extensions = jdx,dx
+mime!chemical/x-kinemage!extensions = kin
+mime!chemical/x-pdb!extensions = pdb,ent
+mime!chemical/x-swissprot!extensions = sw
+mime!chemical/x-vamas-iso14976!extensions = vms
+mime!chemical/x-vmd!extensions = vmd
+mime!chemical/x-xtel!extensions = xtel
+mime!chemical/x-xyz!extensions = xyz
+mime!image/gif!extensions = gif
+mime!image/jpeg!extensions = jpeg,jpg,jpe
+mime!image/pcx!extensions = pcx
+mime!image/png!extensions = png
+mime!image/svg+xml!extensions = svg,svgz
+mime!image/tiff!extensions = tiff,tif
+mime!image/vnd.djvu!extensions = djvu,djv
+mime!image/vnd.wap.wbmp!extensions = wbmp
+mime!image/x-icon!extensions = ico
+mime!image/x-ms-bmp!extensions = bmp
+mime!image/x-photoshop!extensions = psd
+mime!image/x-portable-anymap!extensions = pnm
+mime!image/x-portable-bitmap!extensions = pbm
+mime!image/x-portable-graymap!extensions = pgm
+mime!image/x-portable-pixmap!extensions = ppm
+mime!image/x-xbitmap!extensions = xbm
+mime!image/x-xpixmap!extensions = xpm
+mime!image/x-xwindowdump!extensions = xwd
+mime!model/iges!extensions = igs,iges
+mime!model/mesh!extensions = msh,mesh,silo
+mime!model/vrml!extensions = wrl,vrml
+mime!text/calendar!extensions = ics,icz
+mime!text/comma-separated-values!extensions = csv
+mime!text/css!extensions = css
+mime!text/h323!extensions = 323
+mime!text/html!extensions = html,htm,shtml
+mime!text/iuls!extensions = uls
+mime!text/mathml!extensions = mml
+mime!text/plain!extensions = asc,txt,text,diff,pot
+mime!text/richtext!extensions = rtx
+mime!text/rtf!extensions = rtf
+mime!text/scriptlet!extensions = sct,wsc
+mime!text/tab-separated-values!extensions = tsv
+mime!text/vnd.sun.j2me.app-descriptor!extensions = jad
+mime!text/vnd.wap.wml!extensions = wml
+mime!text/vnd.wap.wmlscript!extensions = wmls
+mime!text/x-boo!extensions = boo
+mime!text/x-c++hdr!extensions = h++,hpp,hxx,hh
+mime!text/x-c++src!extensions = c++,cpp,cxx,cc
+mime!text/x-chdr!extensions = h
+mime!text/x-csh!extensions = csh
+mime!text/x-csrc!extensions = c
+mime!text/x-dsrc!extensions = d
+mime!text/x-haskell!extensions = hs
+mime!text/x-java!extensions = java
+mime!text/x-literate-haskell!extensions = lhs
+mime!text/x-moc!extensions = moc
+mime!text/x-pascal!extensions = p,pas
+mime!text/x-pcs-gcd!extensions = gcd
+mime!text/x-perl!extensions = pl,pm
+mime!text/x-python!extensions = py
+mime!text/x-setext!extensions = etx
+mime!text/x-sh!extensions = sh
+mime!text/x-tcl!extensions = tcl,tk
+mime!text/x-tex!extensions = tex,ltx,sty,cls
+mime!text/x-vcalendar!extensions = vcs
+mime!text/x-vcard!extensions = vcf
+mime!video/dl!extensions = dl
+mime!video/dv!extensions = dif,dv
+mime!video/fli!extensions = fli
+mime!video/gl!extensions = gl
+mime!video/mp4!extensions = mp4
+mime!video/mpeg!extensions = mpeg,mpg,mpe
+mime!video/ogg!extensions = ogv
+mime!video/quicktime!extensions = qt,mov
+mime!video/vnd.mpegurl!extensions = mxu
+mime!video/x-flv!extensions = flv
+mime!video/x-la-asf!extensions = lsf,lsx
+mime!video/x-mng!extensions = mng
+mime!video/x-ms-asf!extensions = asf,asx
+mime!video/x-ms-wm!extensions = wm
+mime!video/x-ms-wmv!extensions = wmv
+mime!video/x-ms-wmx!extensions = wmx
+mime!video/x-ms-wvx!extensions = wvx
+mime!video/x-msvideo!extensions = avi
+mime!video/x-sgi-movie!extensions = movie
+mime!x-conference/x-cooltalk!extensions = ice
+mime!x-world/x-vrml!extensions = vrm,vrml,wrl
+"""
+
+if __name__ == "__main__":
+ main()
107 admin/CTK/CTK/AjaxUpload.py
View
@@ -0,0 +1,107 @@
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+import os
+import tempfile
+from cgi import FieldStorage
+
+from Box import Box
+from Button import Button
+from RawHTML import RawHTML
+from Server import publish, get_scgi
+
+HEADERS = [
+ '<script type="text/javascript" src="/CTK/js/ajaxupload.3.6.js"></script>'
+]
+
+JS = """
+var button = $('#%(opener_widget_id)s');
+var msg = $('#%(id)s .msg');
+
+new AjaxUpload (button, {
+ name: 'file',
+ action: '%(upload_url)s',
+ onSubmit: function (file, ext) {
+ this.disable();
+ msg.html('Uploading');
+
+ interval = window.setInterval(function(){
+ var text = msg.html();
+ if (text.length < 13){
+ msg.html(text + '.');
+ } else {
+ msg.html('Uploading');
+ }
+ }, 200);
+ },
+ onComplete: function (file, response) {
+ window.clearInterval (interval);
+ msg.html('');
+ this.enable();
+ $('#%(id)s').trigger ({'type':'upload_finished', 'filename': file});
+ }
+});
+"""
+
+# The internal POST Receiver and Storage classes are imported from
+# CTK.Uploader().
+#
+from Uploader import UploadRequest
+
+
+class AjaxUpload_Generic (Box):
+ def __init__ (self, opener_widget, props={}, params=None, direct=True):
+ Box.__init__ (self)
+
+ self.id = 'ajax_upload_%d' %(self.uniq_id)
+ self._url_local = '/ajax_upload_%d' %(self.uniq_id)
+ self.props = props.copy()
+ self.opener_widget = opener_widget
+
+ handler = self.props.get('handler')
+ target_dir = self.props.get('target_dir')
+
+ # Widgets
+ msg = Box ({'class': 'msg'}, RawHTML(' '))
+ self += opener_widget
+ self += msg
+
+ # Register the uploader path
+ publish (self._url_local, UploadRequest,
+ handler=handler, target_dir=target_dir, params=params, direct=direct)
+
+ def Render (self):
+ props = {'id': self.id,
+ 'upload_url': self._url_local,
+ 'opener_widget_id': self.opener_widget.id}
+
+ render = Box.Render (self)
+ render.headers += HEADERS
+ render.js += JS %(props)
+
+ return render
+
+
+class AjaxUpload (AjaxUpload_Generic):
+ def __init__ (self, *args, **kwargs):
+ button = Button(_('Upload'))
+ AjaxUpload_Generic.__init__ (self, button, *args, **kwargs)
84 admin/CTK/CTK/Box.py
View
@@ -0,0 +1,84 @@
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+from Widget import Widget
+from Container import Container
+from consts import HTML_JS_BLOCK
+from util import *
+
+HTML = '<div id="%(id)s" %(props)s>%(content)s%(embedded_js)s</div>'
+
+class Box (Container):
+ """
+ Widget for the base DIV element. All arguments are optional.
+
+ Arguments:
+ props: dictionary with properties for the DIV element, such
+ as {'class': 'test', 'display': 'none'}
+
+ content: if provided, it must be a CTK widget
+
+ embed_javascript: True|False. Disabled by default. If
+ enabled, Javascript code associated to the widget will
+ be rendered as part of the DIV definition instead of
+ using a separate Javascript block.
+
+ Examples:
+ box1 = CTK.Box()
+ box2 = CTK.Box({'class': 'test', 'id': 'test-box'},
+ CTK.RawHTML('This is a test box'))
+ """
+ def __init__ (self, props={}, content=None, embed_javascript=False):
+ Container.__init__ (self)
+ self.props = props.copy()
+ self.embed_javascript = embed_javascript
+
+ # Object ID
+ if 'id' in self.props:
+ self.id = self.props.pop('id')
+
+ # Initial value
+ if content:
+ if isinstance (content, Widget):
+ self += content
+ elif type(content) in (list, type):
+ for o in content:
+ self += o
+ else:
+ raise TypeError, 'Unknown type: "%s"' %(type(content))
+
+ def Render (self):
+ render = Container.Render (self)
+
+ if self.embed_javascript and render.js:
+ js = HTML_JS_BLOCK %(render.js)
+ render.js = ''
+ else:
+ js = ''
+
+ props = {'id': self.id,
+ 'props': props_to_str (self.props),
+ 'content': render.html,
+ 'embedded_js': js}
+
+ render.html = HTML %(props)
+ return render
65 admin/CTK/CTK/Button.py
View
@@ -0,0 +1,65 @@
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+from Widget import Widget
+from util import props_to_str
+
+class Button (Widget):
+ """
+ Widget for the BUTTON HTML element. All arguments are optional.
+
+ Arguments:
+ caption: text that should appear in the button. By default,
+ "Submit".
+
+ props: dictionary with properties for HTML element, such as
+ {'class': 'test', 'display': 'none'}
+
+ Examples:
+ button1 = CTK.Button()
+ button2 = CTK.Box('Validate', {'class': 'blue_button'})
+ """
+ def __init__ (self, caption="Submit", props={}):
+ Widget.__init__ (self)
+ self.props = props.copy()
+
+ if 'class' in props:
+ self.props['class'] += " button"
+ else:
+ self.props['class'] = "button"
+
+ self.id = props.pop('id', "button_%d"%(self.uniq_id))
+ self.caption = caption
+
+ # Public interface
+ #
+ def Render (self):
+ id = self.id
+ caption = self.caption
+ props = props_to_str (self.props)
+
+ html = '<button id="%(id)s" %(props)s>%(caption)s</button>' %(locals())
+
+ render = Widget.Render (self)
+ render.html += html
+
+ return render
122 admin/CTK/CTK/Carousel.py
View
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+#
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+from Box import Box
+from List import List
+from Link import Link
+from RawHTML import RawHTML
+
+HEADERS = [
+ '<script type="text/javascript" src="/CTK/js/Carousel.js"></script>'
+]
+
+JS_INIT = """
+$("#%(id)s").Carousel();
+"""
+
+class Carousel (Box):
+ """
+ Widget to render a slideshow box.
+
+ Optional arguments:
+ props: dictionary with properties for HTML element, such as
+ {'class': 'test', 'id': 'snapshots'}
+
+ Example:
+ shots = CTK.Carousel()
+ shots += CTK.Image ({'src': 'image1.png'})
+ shots += CTK.Image ({'src': 'image2.png'})
+ """
+ def __init__ (self, props_={}):
+ props = props_.copy()
+ if 'class' in props:
+ props['class'] += " carousel"
+ else:
+ props['class'] = "carousel"
+
+ Box.__init__ (self, props.copy())
+ self.images = List ({'class': 'overview'})
+ self.pager = List ({'class': 'pager'})
+ self.controls = None
+
+ Box.__iadd__ (self, self.images)
+
+ def __iadd__ (self, widget):
+ link = Link (None, RawHTML ("%s" %(len(self.images.child) +1)))
+
+ self.images += widget
+ self.pager += link
+ self.pager[-1].props['class'] = 'pagenum'
+
+ return self
+
+ def Render (self):
+ # Add pager and arrows if there is more than 1 item
+ if len(self.pager) > 1 and not self.controls:
+ arrows = Box({'class':'arrows'})
+ arrows += Link (None, RawHTML("%s"%(_('left'))), {'class': "buttons prev"})
+ arrows += Link (None, RawHTML("%s"%(_('right'))), {'class': "buttons next"})
+
+ self.controls = Box({'class':'controls'})
+ self.controls += arrows
+ self.controls += self.pager
+
+ Box.__iadd__ (self, self.controls)
+
+ # Render
+ render = Box.Render (self)
+
+ render.headers += HEADERS
+ render.js += JS_INIT %({'id': self.id})
+
+ return render
+
+
+class CarouselThumbnails (Carousel):
+ """
+ Widget to render a slideshow box, with thumbnails.
+
+ Optional arguments:
+ props: dictionary with properties for HTML element, such as
+ {'class': 'test', 'id': 'snapshots'}
+
+ Example:
+ shots = CTK.CarouselThumbnails()
+ shots += CTK.Image ({'src': 'image1.png'})
+ shots += CTK.Image ({'src': 'image2.png'})
+ """
+ def __init__ (self, props_={}):
+ Carousel.__init__ (self, props_.copy())
+
+ def __iadd__ (self, widget):
+ box = Box ({'class': 'carousel-thumbs'})
+ box += RawHTML ("%s" %(len(self.images.child) +1))
+ box += Box ({'class': 'carousel_thumbs-image'}, widget)
+ link = Link (None, Box ({'class': 'carousel_thumbs-link'}, box))
+
+ self.images += widget
+ self.pager += link
+ self.pager[-1].props['class'] = 'pagenum'
+
+ return self
168 admin/CTK/CTK/Checkbox.py
View
@@ -0,0 +1,168 @@
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2010-2011 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+__author__ = 'Alvaro Lopez Ortega <alvaro@alobbs.com>'
+
+from Widget import Widget
+from Container import Container
+from Server import cfg
+from util import *
+
+
+HTML = """
+<input type="checkbox" id="%(id)s" %(props)s />
+"""
+
+CLICK_CHANGE_JS = """
+ $('#%s').each (function() {
+ var checkbox_text = $(this);
+
+ checkbox_text.find('.description').bind ('click', function() {
+ var checkbox = checkbox_text.find('input:checkbox');
+ checkbox.attr("checked", !checkbox.attr("checked"));
+ checkbox.trigger ({type: "change"});
+ });
+ });
+"""
+
+class Checkbox (Widget):
+ """
+ Widget for the base <input type="checkbox"> element. Arguments are optional.
+
+ Arguments:
+ props: dictionary with properties for the HTML element,
+ such as {'name': 'foo', 'id': 'bar', 'class': 'noauto'}.
+
+ noauto: form will not be submitted instantly upon
+ modification of the checkbox.
+
+ Examples:
+ check = CTK.Checkbox({'name': 'chekbox_test', 'class': 'noauto'})
+ """
+ def __init__ (self, props={}):
+ # Sanity check
+ assert type(props) == dict
+
+ Widget.__init__ (self)
+ self._props = props.copy()
+
+ def Render (self):
+ # Deal with a couple of exceptions
+ new_props = self._props.copy()
+
+ if new_props.has_key('checked') and int(new_props.pop('checked')):
+ new_props['checked'] = "checked"
+
+ if new_props.has_key('disabled') and int(new_props.pop('disabled')):
+ new_props['disabled'] = None
+
+ # Render the widget
+ render = Widget.Render (self)
+ render.html += HTML % ({'id': self.id,
+ 'props': props_to_str (new_props)})
+ return render
+
+
+class CheckCfg (Checkbox):
+ """
+ Configuration-Tree based Checkbox widget. Populates the input
+ checkbox with the value of the configuration tree given by key
+ argument if it exists. It accepts properties to pass to the base
+ Checkbox object.
+
+ Arguments:
+ key: key in the configuration tree.
+ default: default value to give to the checkbox.
+ props: additional properties for base Checkbox.
+ """
+ def __init__ (self, key, default, props=None):
+ # Sanity checks
+ assert type(key) == str
+ assert type(default) == bool
+ assert type(props) in (type(None), dict)
+
+ if not props:
+ props = {}
+
+ # Read the key value
+ val = cfg.get_val(key)
+ if not val:
+ props['checked'] = "01"[bool(int(default))]
+ elif val.isdigit():
+ props['checked'] = "01"[bool(int(val))]
+ else:
+ assert False, "Could not handle value: %s"%(val)
+
+ # Other properties
+ props['name'] = key
+
+ # Init parent
+ Checkbox.__init__ (self, props)
+
+
+class CheckboxText (Checkbox):
+ """
+ Widget that extends the base Checkbox widget to display a
+ label/text beside it. It accepts properties to pass to the base
+ Checkbox object.
+
+ Arguments:
+ props: additional properties for base Checkbox.
+ text: text to show beside the checkbox (by default, 'Enabled')
+ """
+ def __init__ (self, props=None, text='Enabled'):
+ Checkbox.__init__ (self, props)
+ self.text = text
+
+ def Render (self):
+ render = Checkbox.Render (self)
+ render.html = '<div id="%s" class="checkbox-text">%s <div class="description">%s</div></div>' %(self.id, render.html, self.text)
+ render.js += CLICK_CHANGE_JS %(self.id)
+ return render
+
+
+class CheckCfgText (CheckCfg):
+ """
+ Configuration-Tree based CheckboxText widget. Populates the input
+ checkbox with the value of the configuration tree given by key
+ argument if it exists. It accepts properties to pass to the base
+ CheckboxText object.
+
+ Arguments:
+ key: key in the configuration tree.
+ default: default value to give to the checkbox.
+ text: text to show beside the checkbox (by default, 'Enabled')
+ props: additional properties for base CheckboxText.
+ """
+ def __init__ (self, key, default, text='Enabled', props=None):
+ assert type(default) == bool
+ assert type(text) == str
+ assert type(props) in (dict, type(None))
+
+ CheckCfg.__init__ (self, key, default, props)
+ self.text = text
+
+ def Render (self):
+ render = CheckCfg.Render (self)
+ render.html = '<div id="%s" class="checkbox-text">%s <div class="description">%s</div></div>' %(self.id, render.html, self.text)
+ render.js += CLICK_CHANGE_JS %(self.id)
+ return render
119 admin/CTK/CTK/Collapsible.py
View
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+#
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2010-2011 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+from Box import Box
+from Widget import Widget
+from RawHTML import RawHTML
+
+class Collapsible (Box):
+ """
+ Widget to show content in an area that can be collapsed and
+ expanded on-click.
+
+ Arguments:
+ titles: Tuple containing two strings to use as
+ titles. Those are shown when the collpasible is
+ minimized and maximized respectively.
+
+ collapsed: Boolean to indicate initial state. Defaults to
+ True.
+
+ Examples:
+ container = CTK.Collapsible (('Show', 'Hide'))
+ container += CTK.RawHTML ('<p>This text can be hidden, or not.</p>')
+ """
+ def __init__ (self, (titles), collapsed=True):
+ Box.__init__ (self, {'class': 'collapsible'})
+
+ self.collapsed = collapsed
+ if collapsed:
+ self.content = Box ({'class': 'collapsible-content', 'style': 'display:none;'})
+ else:
+ self.content = Box ({'class': 'collapsible-content'})
+
+ assert len(titles) == 2
+ self.title_show = Box ({'class': 'collapsible-title'}, titles[0])
+ self.title_hide = Box ({'class': 'collapsible-title'}, titles[1])
+
+ self.title_show.bind ('click', self.__JS_show())
+ self.title_hide.bind ('click', self.__JS_hide())
+
+ # Build up
+ Box.__iadd__ (self, self.title_show)
+ Box.__iadd__ (self, self.title_hide)
+ Box.__iadd__ (self, self.content)
+
+ def __iadd__ (self, content):
+ self.content += content
+ return self
+
+ def __JS_show (self):
+ return self.content.JS_to_show(100) + self.title_hide.JS_to_show() + self.title_show.JS_to_hide()
+
+ def __JS_hide (self):
+ return self.content.JS_to_hide() + self.title_hide.JS_to_hide() + self.title_show.JS_to_show()
+
+ def Render (self):
+ render = Box.Render (self)
+
+ if self.collapsed:
+ render.js += self.__JS_hide()
+ else:
+ render.js += self.__JS_show()
+
+ return render
+
+class CollapsibleEasy (Collapsible):
+ """
+ Widget to show content in an area that can be collapsed and
+ expanded on-click. It works just like the Collapsible, but
+ prepends up/down arrows to the titles to indicate collapse/expand.
+
+ Arguments:
+ titles: Tuple containing two strings to use as
+ titles. Those are shown when the collpasible is
+ minimized and maximized respectively.
+
+ collapsed: Boolean to indicate initial state. Defaults to
+ True.
+
+ Examples:
+ container = CTK.CollapsibleEasy (('Show', 'Hide'))
+ container += CTK.RawHTML ('<p>This text can be hidden, or not.</p>')
+ """
+ def __init__ (self, (titles), collapsed=True):
+ assert len(titles) == 2
+ assert type(titles[0]) == str
+ assert type(titles[1]) == str
+
+ if collapsed:
+ c0 = ""
+ c1 = ""
+ else:
+ c0 = ""
+ c1 = ""
+
+ show = RawHTML(c0 + titles[0])
+ hide = RawHTML(c1 + titles[1])
+ Collapsible.__init__ (self, (show, hide), collapsed)
134 admin/CTK/CTK/Combobox.py
View
@@ -0,0 +1,134 @@
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+from Widget import Widget
+from Server import cfg
+from util import props_to_str
+
+class Combobox (Widget):
+ """
+ Widget for drop-down combo elements.
+
+ Arguments:
+ props: dictionary with properties for the HTML element,
+ such as {'name': 'foo', 'id': 'bar', 'class': 'noauto'}.
+
+ options: set of tuples in the form (value,
+ description), (v2, d2), ...
+
+ Examples:
+ combo = CTK.Combobox({'name': 'language'},
+ [('en', 'English'), ('es', 'Spanish')])
+ """
+ def __init__ (self, props, options):
+ Widget.__init__ (self)
+
+ self.props = props.copy()
+ self._options = options
+
+ if not 'id' in self.props:
+ self.props['id'] = 'Combobox_%s' %(self.uniq_id)
+ self.id = self.props['id']
+
+ def Render (self):
+ selected = self.props.get('selected')
+
+ def render_str (o):
+ if len(o) == 2:
+ name, label = o
+ props = {}
+ elif len(o) == 3:
+ name, label, props = o
+
+ props_str = props_to_str(props)
+ if selected and str(selected) == str(name):
+ return '<option value="%s" selected="true" %s>%s</option>' % (name, props_str, label)
+ else:
+ return '<option value="%s" %s>%s</option>' % (name, props_str, label)
+
+ def render_list (o):
+ if len(o) == 2:
+ name, options = o
+ props = {}
+ elif len(o) == 3:
+ name, options, props = o
+
+ props_str = props_to_str(props)
+ txt = '<optgroup label="%s" %s>' %(name, props_str)
+ for o in options:
+ txt += render_str (o)
+ txt += '</optgroup>'
+ return txt
+
+ # Render entries
+ content = ''
+ for o in self._options:
+ if type(o[1]) == str:
+ content += render_str (o)
+ elif type(o[1]) == list:
+ content += render_list (o)
+ else:
+ raise ValueError
+
+ # Render the container
+ header = ''
+ for p in filter(lambda x: x!='selected', self.props):
+ if self.props[p]:
+ header += ' %s="%s"' %(p, self.props[p])
+ else:
+ header += ' %s' %(p)
+
+ html = '<select%s>%s</select>' %(header, content)
+
+ render = Widget.Render (self)
+ render.html += html
+
+ return render
+
+
+class ComboCfg (Combobox):
+ """
+ Configuration-Tree based Combobox widget. Pre-selects the
+ combo-entry corresponding to the value of the configuration tree
+ given by key argument if it exists. Everything else is like the
+ Combobox widget.
+ """
+ def __init__ (self, key, options, _props={}):
+ props = _props.copy()
+
+ # Read the key value
+ val = cfg.get_val(key)
+ sel = None
+
+ # Look for the selected entry
+ for v,k in options:
+ if v == val:
+ sel = val
+
+ if sel:
+ props['selected'] = sel
+
+ # Other properties
+ props['name'] = key
+
+ # Init parent
+ Combobox.__init__ (self, props, options)
484 admin/CTK/CTK/Config.py
View
@@ -0,0 +1,484 @@
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+import copy
+import types
+
+class ConfigNode (object):
+ def __init__ (self):
+ self._val = None
+ self._child = {}
+
+ # Value
+ #
+ def _get_value (self):
+ return self._val
+ def _set_value (self, val):
+ self._val = val
+
+ value = property (_get_value, _set_value)
+
+ def get_val (self, key, default=None):
+ try:
+ subcfg = self[key]
+ except:
+ return default
+ if not subcfg:
+ return default
+ return subcfg.value
+
+ def get_vals (self, keys, default=None):
+ values = []
+ for k in keys:
+ values += [self.get_val(k)]
+ return values
+
+ # Get child
+ #
+ def _getitem_simple (self, key):
+ if not key in self._child:
+ return None
+
+ r = self._child[key]
+ assert (isinstance(r, ConfigNode))
+ return r
+
+ def _getitem_complex (self, path):
+ node = self
+ for p in path.split('!'):
+ tmp = node[p]
+ if not tmp:
+ return None
+ node = tmp
+ return node
+
+ def __getitem__ (self, path):
+ if '!' in path:
+ return self._getitem_complex (path)
+ else:
+ return self._getitem_simple (path)
+
+ # Add children
+ #
+ def _create_path (self, path):
+ node = self
+ for p in path.split('!'):
+ tmp = node[p]
+ if not tmp:
+ tmp = ConfigNode()
+ node[p] = tmp
+ node = tmp
+ return node
+
+ def _setitem_simple (self, key, val):
+ assert (isinstance(val, ConfigNode))
+ self._child[key] = val
+
+ def __setitem__ (self, key, val):
+ if '!' in key:
+ obj = self[key]
+ if not obj:
+ self._create_path(key)
+
+ if isinstance (val, ConfigNode):
+ if '!' in key:
+ parts = key.split('!')
+ last = parts[-1]
+ prev = reduce (lambda x,y: "%s!%s" % (x,y), parts[:-1])
+ obj = self[prev]
+ obj._child[last] = val
+ else:
+ self._child[key] = val
+ else:
+ if '!' in key:
+ self[key].value = val
+ else:
+ child = self[key]
+ if not child:
+ child = self._create_path (key)
+ child.value = val
+
+ # Modify child
+ #
+ def __delitem__ (self, key):
+ del (self._child[key])
+
+ def __iter__ (self):
+ return iter(self._child)
+
+ # Serialize
+ def serialize (self, path=''):
+ content = ''
+ if self._val is not None:
+ if type(self._val) == types.BooleanType:
+ val = str(int(self._val))
+ else:
+ val = str(self._val)
+ content += '%s = %s\n' % (path, val)
+
+ for name in self._child:
+ if name == 'tmp':
+ continue
+
+ node = self._child[name]
+ if len(path) != 0:
+ new_path = "%s!%s" % (path, name)
+ else:
+ new_path = name
+
+ content += node.serialize (new_path)
+ return content
+
+ # Sub-tree operations
+ def set_value (self, key, val):
+ if not key in self._child:
+ cfg = ConfigNode()
+ self._child[key] = cfg
+ else:
+ cfg = self._child[key]
+
+ cfg.value = val
+
+ def has_child (self):
+ return len(self._child) > 0
+
+ def keys (self):
+ return self._child.keys()
+
+ def __contains__ (self, key):
+ return key in self._child.keys()
+
+ def __cmp__ (self, other):
+ if self._val != other._val:
+ return cmp (self._val, other._val)
+
+ for k in self._child:
+ if not k in other:
+ return 1
+ re = cmp(self._child[k], other[k])
+ if re != 0:
+ return re
+
+ for k in other._child:
+ if not k in self:
+ return -1
+ re = cmp(other[k], self._child[k])
+ if re != 0:
+ return re
+
+ return 0
+
+
+class Config:
+ """
+ Class to represent and interact with the configuration tree. An
+ optional configuration file can be passed as argument on
+ instantiation to load and parse an initial configuration tree.
+ """
+ def __init__ (self, file=None):
+ self.root = ConfigNode()
+ self.root_orig = None
+ self.file = file
+
+ # Build ConfigNode tree
+ if file:
+ self.load()
+
+ def load (self):
+ """Load and Parse the configuration file specified on
+ initialization."""
+ # Load and Parse
+ try:
+ f = open (self.file, "r")
+ except:
+ pass
+ else:
+ self._parse (f.read())
+ f.close()
+
+ # Original copy
+ self.root_orig = copy.deepcopy (self.root)
+
+ def _create_path (self, path):
+ node = self.root
+ for p in path.split('!'):
+ tmp = node[p]
+ if not tmp:
+ tmp = ConfigNode()
+ node[p] = tmp
+ node = tmp
+ return node
+
+ def _parse (self, config_string):
+ for line in config_string.split('\n'):
+ node = self.root
+
+ while len(line) > 1 and line[-1] in " \r\n\t":
+ line = line[:-1]
+
+ if len(line) < 5: continue
+ if line[0] == '#': continue
+
+ try:
+ path, value = line.split (" = ", 1)
+ except:
+ msg = _("ERROR: Couldn't unpack '%s'")
+ print msg % (line)
+ raise
+
+ node = self._create_path (path)
+ node.value = value
+
+ def __str__ (self):
+ return self.root.serialize()
+
+ # Access
+ def __getitem__ (self, path):
+ return self.root[path]
+
+ def clone (self, path_old, path_new):
+ """Clone a given branch into another location in the
+ configuration tree."""
+ parent, parent_path, child_name = self._get_parent_node (path_old)
+ if self.root[path_new]:
+ return True
+ copied = copy.deepcopy (self[path_old])
+ self.set_sub_node (path_new, copied)
+
+ def rename (self, path_old, path_new):
+ """Rename a branch in the configuration tree given by path_old
+ to a new name given by path_new."""
+ error = self.clone (path_old, path_new)
+ if not error:
+ del(self[path_old])
+ return error
+
+ def set_sub_node (self, path, config_node):
+ assert isinstance(config_node, ConfigNode), type(config_node)
+
+ # Top level entry
+ if not '!' in path:
+ self.root[path] = config_node
+ return
+
+ # Deep entries
+ parent, parent_path, child_name = self._get_parent_node (path)
+ if not parent:
+ # Target parent does not exist
+ self._create_path (parent_path)
+ parent, parent_path, child_name = self._get_parent_node (path)
+
+ if not parent._child.has_key(child_name):
+ parent._create_path(child_name)
+
+ parent._child[child_name] = config_node
+
+ def __setitem__ (self, path, val):
+ if not isinstance (val, ConfigNode):
+ if not val or len(val) == 0:
+ del (self[path])
+ return
+
+ tmp = self[path]
+ if not tmp:
+ tmp = self._create_path (path)
+
+ tmp.value = val
+
+ def _get_parent_node (self, path):
+ preg = path.split('!')
+ last = preg[-1]
+ pres = reduce (lambda x,y: "%s!%s" % (x,y), preg[:-1])
+ return (self[pres], pres, last)
+
+ def get_val (self, path, default=None):
+ """Return the value of a configuration entry given by the
+ 'path' argument. If not found, return the value of the
+ optional 'default' argument."""
+ return self.root.get_val (path, default)
+
+ def get_vals (self, paths, default=None):
+ return self.root.get_vals (paths, default)
+
+ def __delitem__ (self, path):
+ if '!' in path:
+ parent, parent_path, child_name = self._get_parent_node (path)
+ if parent and parent._child.has_key(child_name):
+ del (parent._child[child_name])
+ else:
+ if path in self.root.keys():
+ del (self.root[path])
+
+ def keys (self, path):
+ """Show keys for a given configuration path."""
+ tmp = self[path]
+ if not tmp:
+ return []
+ return tmp.keys()
+
+ def pop (self, key):
+ """Pop an element from the configuration tree given by
+ argument key."""
+ tmp = self.get_val(key)
+ del (self[key])
+ return tmp
+
+ # Serialization
+ def serialize (self):
+ """Dump the contents of the configuration tree into a
+ string."""
+ def sorter(x,y):
+ order = ['config', 'server', 'vserver', 'source', 'icons', 'mime', 'admin']
+ a = x.split('!')
+ b = y.split('!')
+ try:
+ ai = order.index(a[0])
+ bi = order.index(b[0])
+ except:
+ return cmp(x,y)
+
+ # Different tags
+ if ai > bi:
+ return 1
+ elif ai < bi:
+ return -1
+
+ # Sort rules: reverse
+ if ((len(a) > 3) and
+ (a[0] == b[0] == 'vserver') and
+ (a[1] == b[1]) and
+ (a[2] == b[2] == 'rule')):
+ re = cmp (int(b[3]), int(a[3]))
+ if re != 0:
+ return re
+
+ return cmp(x,y)
+
+ tmp = self.root.serialize().split('\n')
+ tmp.sort(sorter)
+ return '\n'.join (filter (lambda x: len(x) > 1, tmp))
+
+ def save (self):
+ """Save current configuration tree into the file specified on
+ initialization. Try to make a copy with the '.backup'
+ extension if possible."""
+ # Try to make a copy
+ try:
+ t = open (self.file+'.backup', 'w+')
+ s = open (self.file, 'r')
+ t.write (s.read())
+ t.close()
+ s.close()
+ except:
+ print _("Could not copy configuration to ") + self.file + '.backup'
+
+ # Write the new one
+ cfg = self.serialize()
+
+ t = open (self.file, 'w+')
+ t.write (cfg)
+ t.close()
+
+ # Update the original tree
+ self.root_orig = copy.deepcopy (self.root)
+
+ # Checks
+ def is_writable (self):
+ """Check if configuration file is writeable."""
+ import os
+
+ if not os.path.exists (self.file):
+ return False
+ return os.access (self.file, os.W_OK)
+
+ def has_tree (self):
+ """Check if configuration tree exists."""
+ return len(self.root._child) > 0
+
+ # Utilities
+ def get_next_entry_prefix (self, pre):
+ """Return next element to insert into a configuration node
+ given by the 'pre' prefix."""
+ entries = [int(x) for x in self.keys(pre)]
+ entries.sort()
+
+ if not entries:
+ return '%s!1'%(pre)
+
+ return '%s!%d'%(pre, entries[-1] + 1)
+
+ def get_lowest_entry (self, pre):
+ """Return first existing element of a configuration node given
+ by the 'pre' prefix."""
+ entries = [int(x) for x in self.keys(pre)]
+ entries.sort()
+
+ if entries:
+ return entries[0]
+
+ return 1
+
+ def normalize (self, pre, step=10):
+ """Reenumerate the branch given by the 'pre' prefix for
+ normalization. An optional step can be provided."""
+ keys = self.keys(pre)
+ keys.sort (lambda x,y: cmp(int(x),int(y)))
+
+ del (self['tmp!normalize'])
+
+ n = step
+ for k in keys:
+ self.clone ('%s!%s'%(pre, k), 'tmp!normalize!%s!%s'%(pre,n))
+ n += step
+
+ del (self[pre])
+ if self['tmp!normalize']:
+ self.rename ('tmp!normalize!%s'%(pre), pre)
+
+ def apply_chunk (self, chunk):
+ """Insert a configuration chunk into the configuration tree,
+ all at once. This is an in-memory operation. Manual steps must
+ be taken to update the configuration file if needed."""
+ lines = [l.strip() for l in chunk.split('\n')]
+ lines = filter (lambda x: len(x) and x[0] != '#', lines)
+
+ for line in lines:
+ left, right = line.split (" = ", 2)
+ self[left] = right
+
+ def has_changed (self):
+ """Check if configuration tree differs from the last one that
+ was saved to the configuration file."""
+ root = copy.deepcopy (self.root)
+ orig = copy.deepcopy (self.root_orig)
+
+ if not root and orig:
+ return True
+ if not orig and root:
+ return True
+
+ if 'tmp' in root:
+ del (root['tmp'])
+ if 'tmp' in orig:
+ del (orig['tmp'])
+
+ return not root == orig
62 admin/CTK/CTK/Container.py
View
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# CTK: Cherokee Toolkit
+#
+# Authors:
+# Alvaro Lopez Ortega <alvaro@alobbs.com>
+#
+# Copyright (C) 2009 Alvaro Lopez Ortega
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+from Widget import Widget
+
+class Container (Widget):
+ """
+ Base container widget. Calling the Render method will produce the
+ HTML associated with the widgets contained within. Thus, if no
+ such widget exists, no HTML will be rendered.
+ """
+ def __init__ (self):
+ Widget.__init__ (self)
+ self.child = []
+
+ def __getitem__ (self, n):
+ return self.child[n]
+
+ def __len__ (self):