utopia-wiki 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/development.yml +62 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.yarnrc +1 -0
- data/Gemfile +4 -0
- data/README.md +46 -0
- data/bake/utopia/wiki.rb +13 -0
- data/lib/components/.yarn-integrity +19 -0
- data/lib/components/jquery-litebox/README.md +66 -0
- data/lib/components/jquery-litebox/bower.json +27 -0
- data/lib/components/jquery-litebox/dist/jquery.litebox.css +23 -0
- data/lib/components/jquery-litebox/dist/jquery.litebox.gallery.css +48 -0
- data/lib/components/jquery-litebox/dist/jquery.litebox.js +30 -0
- data/lib/components/jquery-litebox/example/index.html +69 -0
- data/lib/components/jquery-litebox/example/jquery.min.js +4 -0
- data/lib/components/jquery-litebox/example/sample_images/large/IMG_3340.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/large/IMG_3341.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/large/IMG_3344.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/large/IMG_3351.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/medium/IMG_3340.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/medium/IMG_3341.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/medium/IMG_3344.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/medium/IMG_3351.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/small/IMG_3340.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/small/IMG_3341.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/small/IMG_3344.jpg +0 -0
- data/lib/components/jquery-litebox/example/sample_images/small/IMG_3351.jpg +0 -0
- data/lib/components/jquery-litebox/package.json +29 -0
- data/lib/components/jquery-syntax/Gemfile +5 -0
- data/lib/components/jquery-syntax/LICENSE.txt +19 -0
- data/lib/components/jquery-syntax/NOTES.txt +20 -0
- data/lib/components/jquery-syntax/README.md +95 -0
- data/lib/components/jquery-syntax/Rakefile +211 -0
- data/lib/components/jquery-syntax/bower.json +25 -0
- data/lib/components/jquery-syntax/config.ru +4 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.apache.css +12 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.applescript.css +5 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.assembly.css +8 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.bash-script.css +6 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.bash.css +4 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.clang.css +6 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.css.css +14 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.diff.css +16 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.html.css +5 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.ocaml.css +3 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.protobuf.css +2 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.python.css +6 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.ruby.css +2 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.brush.xml.css +18 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.core.css +58 -0
- data/lib/components/jquery-syntax/dist/base/jquery.syntax.editor.css +6 -0
- data/lib/components/jquery-syntax/dist/base/theme.js +1 -0
- data/lib/components/jquery-syntax/dist/bright/jquery.syntax.core.css +27 -0
- data/lib/components/jquery-syntax/dist/bright/theme.js +1 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.apache.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.applescript.js +5 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.assembly.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.bash-script.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.bash.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.basic.js +5 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.clang.js +5 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.csharp.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.css.js +5 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.diff.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.go.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.haskell.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.html.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.io.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.java.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.javascript.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.kai.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.lisp.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.lua.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.nginx.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.ocaml.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.ooc.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.pascal.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.perl5.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.php-script.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.php.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.plain.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.protobuf.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.python.js +5 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.ruby.js +5 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.scala.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.smalltalk.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.sql.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.super-collider.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.swift.js +3 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.trenni.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.xml.js +4 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.brush.yaml.js +2 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.cache.js +7 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.core.js +34 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.editor.js +11 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.js +8 -0
- data/lib/components/jquery-syntax/dist/jquery.syntax.min.js +13 -0
- data/lib/components/jquery-syntax/dist/paper/jquery.syntax.core.css +31 -0
- data/lib/components/jquery-syntax/dist/paper/theme.js +1 -0
- data/lib/components/jquery-syntax/examples/ex.applescript.html +120 -0
- data/lib/components/jquery-syntax/examples/ex.asm.html +43 -0
- data/lib/components/jquery-syntax/examples/ex.bash.html +139 -0
- data/lib/components/jquery-syntax/examples/ex.clang.html +337 -0
- data/lib/components/jquery-syntax/examples/ex.css.html +48 -0
- data/lib/components/jquery-syntax/examples/ex.diff.html +1226 -0
- data/lib/components/jquery-syntax/examples/ex.editor.html +28 -0
- data/lib/components/jquery-syntax/examples/ex.html.html +134 -0
- data/lib/components/jquery-syntax/examples/ex.javascript.html +330 -0
- data/lib/components/jquery-syntax/examples/ex.ooc.html +119 -0
- data/lib/components/jquery-syntax/examples/ex.php.html +54 -0
- data/lib/components/jquery-syntax/examples/ex.python.html +1510 -0
- data/lib/components/jquery-syntax/examples/ex.ruby.html +358 -0
- data/lib/components/jquery-syntax/examples/ex.swift.html +90 -0
- data/lib/components/jquery-syntax/examples/index.css +18 -0
- data/lib/components/jquery-syntax/examples/jquery-1.6.min.js +16 -0
- data/lib/components/jquery-syntax/examples/tests.html +71 -0
- data/lib/components/jquery-syntax/examples/wrapping-flex.html +71 -0
- data/lib/components/jquery-syntax/examples/wrapping.html +181 -0
- data/lib/components/jquery-syntax/ext/closure/COPYING +202 -0
- data/lib/components/jquery-syntax/ext/closure/README +292 -0
- data/lib/components/jquery-syntax/ext/closure/compiler.jar +0 -0
- data/lib/components/jquery-syntax/ext/theme.rb +85 -0
- data/lib/components/jquery-syntax/install.yaml +9 -0
- data/lib/components/jquery-syntax/jQuery.Syntax.artx/Preview/preview.png +0 -0
- data/lib/components/jquery-syntax/jQuery.Syntax.artx/doc.thread +0 -0
- data/lib/components/jquery-syntax/package.json +31 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.apache.js +41 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.applescript.js +57 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.assembly.js +37 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.bash-script.js +67 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.bash.js +33 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.basic.js +51 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.clang.js +89 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.csharp.js +47 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.css.js +80 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.diff.js +24 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.go.js +47 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.haskell.js +45 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.html.js +66 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.io.js +45 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.java.js +45 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.javascript.js +42 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.kai.js +29 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.lisp.js +34 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.lua.js +44 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.nginx.js +30 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.ocaml.js +73 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.ooc.js +46 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.pascal.js +51 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.perl5.js +52 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.php-script.js +48 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.php.js +15 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.plain.js +10 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.protobuf.js +43 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.python.js +44 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.ruby.js +77 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.scala.js +44 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.smalltalk.js +29 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.sql.js +31 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.super-collider.js +57 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.swift.js +55 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.trenni.js +35 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.xml.js +50 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.brush.yaml.js +29 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.core.js +1114 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.editor.js +291 -0
- data/lib/components/jquery-syntax/source/jquery.syntax.js +258 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.apache.sass +23 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.applescript.sass +11 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.assembly.sass +16 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.bash-script.sass +14 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.bash.sass +11 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.clang.sass +12 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.css.sass +25 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.diff.sass +25 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.html.sass +12 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.ocaml.sass +8 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.protobuf.sass +7 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.python.sass +12 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.ruby.sass +9 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.brush.xml.sass +30 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.core.sass +86 -0
- data/lib/components/jquery-syntax/themes/base/jquery.syntax.editor.sass +12 -0
- data/lib/components/jquery-syntax/themes/bright/_config.yaml +2 -0
- data/lib/components/jquery-syntax/themes/bright/jquery.syntax.core.sass +42 -0
- data/lib/components/jquery-syntax/themes/paper/_config.yaml +2 -0
- data/lib/components/jquery-syntax/themes/paper/jquery.syntax.core.sass +47 -0
- data/lib/components/jquery/AUTHORS.txt +327 -0
- data/lib/components/jquery/LICENSE.txt +20 -0
- data/lib/components/jquery/README.md +62 -0
- data/lib/components/jquery/bower.json +14 -0
- data/lib/components/jquery/dist/jquery.js +10872 -0
- data/lib/components/jquery/dist/jquery.min.js +2 -0
- data/lib/components/jquery/dist/jquery.min.map +1 -0
- data/lib/components/jquery/dist/jquery.slim.js +8777 -0
- data/lib/components/jquery/dist/jquery.slim.min.js +2 -0
- data/lib/components/jquery/dist/jquery.slim.min.map +1 -0
- data/lib/components/jquery/external/sizzle/LICENSE.txt +36 -0
- data/lib/components/jquery/external/sizzle/dist/sizzle.js +2478 -0
- data/lib/components/jquery/external/sizzle/dist/sizzle.min.js +3 -0
- data/lib/components/jquery/external/sizzle/dist/sizzle.min.map +1 -0
- data/lib/components/jquery/package.json +117 -0
- data/lib/components/jquery/src/ajax.js +873 -0
- data/lib/components/jquery/src/ajax/jsonp.js +103 -0
- data/lib/components/jquery/src/ajax/load.js +77 -0
- data/lib/components/jquery/src/ajax/script.js +74 -0
- data/lib/components/jquery/src/ajax/var/location.js +5 -0
- data/lib/components/jquery/src/ajax/var/nonce.js +5 -0
- data/lib/components/jquery/src/ajax/var/rquery.js +5 -0
- data/lib/components/jquery/src/ajax/xhr.js +170 -0
- data/lib/components/jquery/src/attributes.js +13 -0
- data/lib/components/jquery/src/attributes/attr.js +141 -0
- data/lib/components/jquery/src/attributes/classes.js +186 -0
- data/lib/components/jquery/src/attributes/prop.js +143 -0
- data/lib/components/jquery/src/attributes/support.js +33 -0
- data/lib/components/jquery/src/attributes/val.js +191 -0
- data/lib/components/jquery/src/callbacks.js +236 -0
- data/lib/components/jquery/src/core.js +400 -0
- data/lib/components/jquery/src/core/DOMEval.js +43 -0
- data/lib/components/jquery/src/core/access.js +72 -0
- data/lib/components/jquery/src/core/camelCase.js +23 -0
- data/lib/components/jquery/src/core/init.js +129 -0
- data/lib/components/jquery/src/core/isAttached.js +26 -0
- data/lib/components/jquery/src/core/nodeName.js +13 -0
- data/lib/components/jquery/src/core/parseHTML.js +65 -0
- data/lib/components/jquery/src/core/parseXML.js +30 -0
- data/lib/components/jquery/src/core/ready-no-deferred.js +97 -0
- data/lib/components/jquery/src/core/ready.js +86 -0
- data/lib/components/jquery/src/core/readyException.js +13 -0
- data/lib/components/jquery/src/core/stripAndCollapse.js +14 -0
- data/lib/components/jquery/src/core/support.js +20 -0
- data/lib/components/jquery/src/core/toType.js +20 -0
- data/lib/components/jquery/src/core/var/rsingleTag.js +7 -0
- data/lib/components/jquery/src/css.js +494 -0
- data/lib/components/jquery/src/css/addGetHookIf.js +26 -0
- data/lib/components/jquery/src/css/adjustCSS.js +74 -0
- data/lib/components/jquery/src/css/curCSS.js +65 -0
- data/lib/components/jquery/src/css/finalPropName.js +42 -0
- data/lib/components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
- data/lib/components/jquery/src/css/showHide.js +105 -0
- data/lib/components/jquery/src/css/support.js +133 -0
- data/lib/components/jquery/src/css/var/cssExpand.js +5 -0
- data/lib/components/jquery/src/css/var/getStyles.js +17 -0
- data/lib/components/jquery/src/css/var/isHiddenWithinTree.js +34 -0
- data/lib/components/jquery/src/css/var/rboxStyle.js +7 -0
- data/lib/components/jquery/src/css/var/rnumnonpx.js +7 -0
- data/lib/components/jquery/src/css/var/swap.js +26 -0
- data/lib/components/jquery/src/data.js +180 -0
- data/lib/components/jquery/src/data/Data.js +162 -0
- data/lib/components/jquery/src/data/var/acceptData.js +19 -0
- data/lib/components/jquery/src/data/var/dataPriv.js +7 -0
- data/lib/components/jquery/src/data/var/dataUser.js +7 -0
- data/lib/components/jquery/src/deferred.js +399 -0
- data/lib/components/jquery/src/deferred/exceptionHook.js +21 -0
- data/lib/components/jquery/src/deprecated.js +87 -0
- data/lib/components/jquery/src/deprecated/ajax-event-alias.js +22 -0
- data/lib/components/jquery/src/deprecated/event.js +48 -0
- data/lib/components/jquery/src/dimensions.js +57 -0
- data/lib/components/jquery/src/effects.js +701 -0
- data/lib/components/jquery/src/effects/Tween.js +125 -0
- data/lib/components/jquery/src/effects/animatedSelector.js +15 -0
- data/lib/components/jquery/src/event.js +892 -0
- data/lib/components/jquery/src/event/focusin.js +58 -0
- data/lib/components/jquery/src/event/support.js +11 -0
- data/lib/components/jquery/src/event/trigger.js +201 -0
- data/lib/components/jquery/src/exports/amd.js +26 -0
- data/lib/components/jquery/src/exports/global.js +34 -0
- data/lib/components/jquery/src/jquery.js +41 -0
- data/lib/components/jquery/src/manipulation.js +480 -0
- data/lib/components/jquery/src/manipulation/_evalUrl.js +32 -0
- data/lib/components/jquery/src/manipulation/buildFragment.js +106 -0
- data/lib/components/jquery/src/manipulation/getAll.js +32 -0
- data/lib/components/jquery/src/manipulation/setGlobalEval.js +22 -0
- data/lib/components/jquery/src/manipulation/support.js +41 -0
- data/lib/components/jquery/src/manipulation/var/rscriptType.js +5 -0
- data/lib/components/jquery/src/manipulation/var/rtagName.js +8 -0
- data/lib/components/jquery/src/manipulation/wrapMap.js +30 -0
- data/lib/components/jquery/src/offset.js +238 -0
- data/lib/components/jquery/src/queue.js +145 -0
- data/lib/components/jquery/src/queue/delay.js +24 -0
- data/lib/components/jquery/src/selector-native.js +241 -0
- data/lib/components/jquery/src/selector-sizzle.js +19 -0
- data/lib/components/jquery/src/selector.js +3 -0
- data/lib/components/jquery/src/serialize.js +136 -0
- data/lib/components/jquery/src/traversing.js +198 -0
- data/lib/components/jquery/src/traversing/findFilter.js +97 -0
- data/lib/components/jquery/src/traversing/var/dir.js +22 -0
- data/lib/components/jquery/src/traversing/var/rneedsContext.js +8 -0
- data/lib/components/jquery/src/traversing/var/siblings.js +17 -0
- data/lib/components/jquery/src/var/ObjectFunctionString.js +7 -0
- data/lib/components/jquery/src/var/arr.js +5 -0
- data/lib/components/jquery/src/var/class2type.js +6 -0
- data/lib/components/jquery/src/var/document.js +5 -0
- data/lib/components/jquery/src/var/documentElement.js +7 -0
- data/lib/components/jquery/src/var/flat.js +16 -0
- data/lib/components/jquery/src/var/fnToString.js +7 -0
- data/lib/components/jquery/src/var/getProto.js +5 -0
- data/lib/components/jquery/src/var/hasOwn.js +7 -0
- data/lib/components/jquery/src/var/indexOf.js +7 -0
- data/lib/components/jquery/src/var/isFunction.js +13 -0
- data/lib/components/jquery/src/var/isWindow.js +8 -0
- data/lib/components/jquery/src/var/pnum.js +5 -0
- data/lib/components/jquery/src/var/push.js +7 -0
- data/lib/components/jquery/src/var/rcheckableType.js +5 -0
- data/lib/components/jquery/src/var/rcssNum.js +9 -0
- data/lib/components/jquery/src/var/rnothtmlwhite.js +8 -0
- data/lib/components/jquery/src/var/slice.js +7 -0
- data/lib/components/jquery/src/var/support.js +6 -0
- data/lib/components/jquery/src/var/toString.js +7 -0
- data/lib/components/jquery/src/wrap.js +78 -0
- data/lib/utopia/wiki.rb +80 -0
- data/lib/utopia/wiki/version.rb +27 -0
- data/package.json +6 -0
- data/pages/_editor.xnode +21 -0
- data/pages/_heading.xnode +2 -0
- data/pages/_listing.xnode +23 -0
- data/pages/_navigation.xnode +33 -0
- data/pages/_page.xnode +32 -0
- data/pages/_thumbnail.xnode +8 -0
- data/pages/controller.rb +77 -0
- data/pages/create.xnode +15 -0
- data/pages/edit.xnode +10 -0
- data/pages/errors/exception.xnode +5 -0
- data/pages/errors/file-not-found.xnode +5 -0
- data/pages/links.yaml +2 -0
- data/pages/show.xnode +15 -0
- data/public/.nojekyll +0 -0
- data/public/_components/jquery-litebox/jquery.litebox.css +23 -0
- data/public/_components/jquery-litebox/jquery.litebox.gallery.css +48 -0
- data/public/_components/jquery-litebox/jquery.litebox.js +30 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +12 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +5 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +8 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +6 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +4 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +6 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.css.css +14 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +16 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.html.css +5 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +3 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +2 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.python.css +6 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +2 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +18 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.core.css +58 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.editor.css +6 -0
- data/public/_components/jquery-syntax/base/theme.js +1 -0
- data/public/_components/jquery-syntax/bright/jquery.syntax.core.css +27 -0
- data/public/_components/jquery-syntax/bright/theme.js +1 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.apache.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.applescript.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.assembly.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.bash.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.basic.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.clang.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.csharp.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.css.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.diff.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.go.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.haskell.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.html.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.io.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.java.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.javascript.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.kai.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.lisp.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.lua.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.nginx.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.ooc.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.pascal.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.perl5.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.php-script.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.php.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.plain.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.python.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.ruby.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.scala.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.sql.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.swift.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.trenni.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.xml.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.yaml.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.cache.js +7 -0
- data/public/_components/jquery-syntax/jquery.syntax.core.js +34 -0
- data/public/_components/jquery-syntax/jquery.syntax.editor.js +11 -0
- data/public/_components/jquery-syntax/jquery.syntax.js +8 -0
- data/public/_components/jquery-syntax/jquery.syntax.min.js +13 -0
- data/public/_components/jquery-syntax/paper/jquery.syntax.core.css +31 -0
- data/public/_components/jquery-syntax/paper/theme.js +1 -0
- data/public/_components/jquery/jquery.js +10872 -0
- data/public/_components/jquery/jquery.min.js +2 -0
- data/public/_components/jquery/jquery.min.map +1 -0
- data/public/_components/jquery/jquery.slim.js +8777 -0
- data/public/_components/jquery/jquery.slim.min.js +2 -0
- data/public/_components/jquery/jquery.slim.min.map +1 -0
- data/public/_static/icon.png +0 -0
- data/public/_static/site.css +191 -0
- data/utopia-wiki.gemspec +39 -0
- data/wiki/Gemfile +10 -0
- data/wiki/config.ru +7 -0
- data/wiki/pages/_logos/Async.png +0 -0
- data/wiki/pages/_logos/Falcon.png +0 -0
- data/wiki/pages/_logos/Utopia.png +0 -0
- data/wiki/pages/index.en.md +62 -0
- data/wiki/pages/index.md +57 -0
- data/wiki/pages/links.yaml +2 -0
- data/wiki/pages/usage/merging/index.md +3 -0
- data/yarn.lock +22 -0
- metadata +675 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<link rel="stylesheet" href="index.css" type="text/css" media="screen" />
|
5
|
+
|
6
|
+
<script src="jquery-1.6.min.js" type="text/javascript"></script>
|
7
|
+
<script src="../dist/jquery.syntax.js" type="text/javascript"></script>
|
8
|
+
<script src="../dist/jquery.syntax.cache.js" type="text/javascript"></script>
|
9
|
+
|
10
|
+
<script type="text/javascript">
|
11
|
+
$(function() {
|
12
|
+
jQuery.syntax();
|
13
|
+
});
|
14
|
+
</script>
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<h1>Syntax: OOC</h1>
|
18
|
+
|
19
|
+
<pre><code class="syntax brush-ooc">
|
20
|
+
include stdint, stdlib, memory, ./myheader // C includes, "./" means relative
|
21
|
+
use gtk, yajit // .use files define include paths, libraries, sourcepath extensions
|
22
|
+
import rock/middle/[FunctionCall, VariableAccess, Expression], gtk/Button // import other ooc files
|
23
|
+
|
24
|
+
Representable: interface {
|
25
|
+
toString: func -> String
|
26
|
+
}
|
27
|
+
|
28
|
+
String: cover from Char* implements Representable {
|
29
|
+
length: extern(strlen) func -> Int
|
30
|
+
toString: func -> String { this } // implicit return
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Dereference is actually a node used in rock (ooc compiler in ooc)
|
35
|
+
* You generate html docs with rock+sonofaj+sphinx, see http://docs.ooc-lang.org
|
36
|
+
* @author nddrylliog
|
37
|
+
*/
|
38
|
+
Dereference: class extends Expression implements Representable {
|
39
|
+
|
40
|
+
expr: Expression
|
41
|
+
count := 0
|
42
|
+
|
43
|
+
/* ~ is a suffix, =expr is an Assign-arg, .token is a Member-arg */
|
44
|
+
init: func ~addressOf (=expr, .token) {
|
45
|
+
super(token)
|
46
|
+
}
|
47
|
+
|
48
|
+
accept: func (visitor: Visitor) {
|
49
|
+
visitor visitDereference(this)
|
50
|
+
}
|
51
|
+
|
52
|
+
getType: func -> Type { expr getType() ? expr getType() dereference() : null }
|
53
|
+
|
54
|
+
toString: func -> String {
|
55
|
+
return expr toString() + "@"
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* @return Responses OK if the node is resolved now, Responses LOOP otherwise
|
60
|
+
*/
|
61
|
+
resolve: func (trail: Trail, res: Resolver) -> Response {
|
62
|
+
|
63
|
+
trail push(this)
|
64
|
+
{
|
65
|
+
response := expr resolve(trail, res)
|
66
|
+
if(!response ok()) {
|
67
|
+
trail pop(this)
|
68
|
+
return response
|
69
|
+
}
|
70
|
+
}
|
71
|
+
trail pop(this)
|
72
|
+
|
73
|
+
return Responses OK
|
74
|
+
|
75
|
+
}
|
76
|
+
|
77
|
+
replace: func (oldie, kiddo: Node) -> Bool {
|
78
|
+
// here the match is used implicitly for the returne xception
|
79
|
+
match oldie {
|
80
|
+
case expr => expr = kiddo; true
|
81
|
+
case => false
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
}
|
86
|
+
|
87
|
+
pointerFiddling: func (p: Int*) -> Float* {
|
88
|
+
printf("%d, %d, %d\n", p@, (p+1)@, (p+2)@)
|
89
|
+
// qualifiers are okay in decl-assigns, casting is done with 'as'
|
90
|
+
i := static const 42 as Float
|
91
|
+
return i&
|
92
|
+
}
|
93
|
+
|
94
|
+
reference: func (i: Int@) {
|
95
|
+
i = 4
|
96
|
+
}
|
97
|
+
|
98
|
+
main: func {
|
99
|
+
Dereference new(expr, token)
|
100
|
+
a := 3
|
101
|
+
reference(a&)
|
102
|
+
"a = %d" format(a) println()
|
103
|
+
}
|
104
|
+
|
105
|
+
List: class <T> extends Enumerable<T> {
|
106
|
+
|
107
|
+
data: T*
|
108
|
+
|
109
|
+
get: func (i: Int) -> T {
|
110
|
+
data[i]
|
111
|
+
}
|
112
|
+
|
113
|
+
}
|
114
|
+
|
115
|
+
"Bye world!" println()
|
116
|
+
</code></pre>
|
117
|
+
|
118
|
+
</body>
|
119
|
+
</html>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<link rel="stylesheet" href="index.css" type="text/css" media="screen" />
|
5
|
+
|
6
|
+
<script src="jquery-1.6.min.js" type="text/javascript"></script>
|
7
|
+
<script src="../dist/jquery.syntax.js" type="text/javascript"></script>
|
8
|
+
<script src="../dist/jquery.syntax.cache.js" type="text/javascript"></script>
|
9
|
+
|
10
|
+
<script type="text/javascript">
|
11
|
+
$(function() {
|
12
|
+
jQuery.syntax();
|
13
|
+
});
|
14
|
+
</script>
|
15
|
+
|
16
|
+
</head>
|
17
|
+
<body>
|
18
|
+
<h1>Syntax: PHP</h1>
|
19
|
+
|
20
|
+
<pre><code class="syntax php"><?php
|
21
|
+
$curl = curl_init();
|
22
|
+
$options = array(CURLOPT_URL => 'http://api.twitter.com/1/statuses/public_timeline.json', CURLOPT_RETURNTRANSFER => true);
|
23
|
+
curl_setopt_array($curl, $options);
|
24
|
+
$json = curl_exec($curl);
|
25
|
+
$obj = json_decode($json);
|
26
|
+
$val5 = trim($_GET['val5']);
|
27
|
+
$val10 = trim($_GET['val10']);
|
28
|
+
$val20 = trim($_GET['val20']);
|
29
|
+
$count = -1;
|
30
|
+
if($val5){$count = 4;}
|
31
|
+
if($val10){$count = 9;}
|
32
|
+
if($val20){$count = 19;}
|
33
|
+
if($val1){$count = -1;}
|
34
|
+
if($count<0){
|
35
|
+
echo "<img class='twitter-bird' src='twitter-bird.png' width='490px' height='315px' />";
|
36
|
+
} else {
|
37
|
+
if($obj){
|
38
|
+
foreach($obj as $var => $value)
|
39
|
+
{
|
40
|
+
if($var<=$count){
|
41
|
+
echo "<div id='user-tweets-container'>";
|
42
|
+
echo "<a class='a-img' href='http://www.twitter.com/" . $obj[$var]->user->screen_name . "' target='_blank'><img src='" . $obj[$var]->user->profile_image_url . "' width='48px' height='48px'/></a>";
|
43
|
+
echo "<p class='text'><a class='screen_name' href='http://www.twitter.com/" . $obj[$var]->user->screen_name . "' target='_blank'>" . $obj[$var]->user->screen_name . "</a>&nbsp;";
|
44
|
+
echo $obj[$var]->text . "</p><br/>";
|
45
|
+
echo "</div>";
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}else{
|
49
|
+
echo "<p class='text'><br>Not able to retrieve Tweets... Please try again later...</p><br/>";
|
50
|
+
}
|
51
|
+
}
|
52
|
+
?></code></pre>
|
53
|
+
</body>
|
54
|
+
</html>
|
@@ -0,0 +1,1510 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<link rel="stylesheet" href="index.css" type="text/css" media="screen" />
|
5
|
+
|
6
|
+
<script src="jquery-1.6.min.js" type="text/javascript"></script>
|
7
|
+
<script src="../dist/jquery.syntax.js" type="text/javascript"></script>
|
8
|
+
<script src="../dist/jquery.syntax.cache.js" type="text/javascript"></script>
|
9
|
+
|
10
|
+
<script type="text/javascript">
|
11
|
+
$(function() {
|
12
|
+
jQuery.syntax();
|
13
|
+
});
|
14
|
+
</script>
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<h1>Syntax: Python</h1>
|
18
|
+
|
19
|
+
<pre><code class="syntax brush-python">#
|
20
|
+
# XML-RPC CLIENT LIBRARY
|
21
|
+
# $Id: xmlrpclib.py 41594 2005-12-04 19:11:17Z andrew.kuchling $
|
22
|
+
#
|
23
|
+
# an XML-RPC client interface for Python.
|
24
|
+
#
|
25
|
+
# the marshalling and response parser code can also be used to
|
26
|
+
# implement XML-RPC servers.
|
27
|
+
#
|
28
|
+
# Notes:
|
29
|
+
# this version is designed to work with Python 2.1 or newer.
|
30
|
+
#
|
31
|
+
# History:
|
32
|
+
# 1999-01-14 fl Created
|
33
|
+
# 1999-01-15 fl Changed dateTime to use localtime
|
34
|
+
# 1999-01-16 fl Added Binary/base64 element, default to RPC2 service
|
35
|
+
# 1999-01-19 fl Fixed array data element (from Skip Montanaro)
|
36
|
+
# 1999-01-21 fl Fixed dateTime constructor, etc.
|
37
|
+
# 1999-02-02 fl Added fault handling, handle empty sequences, etc.
|
38
|
+
# 1999-02-10 fl Fixed problem with empty responses (from Skip Montanaro)
|
39
|
+
# 1999-06-20 fl Speed improvements, pluggable parsers/transports (0.9.8)
|
40
|
+
# 2000-11-28 fl Changed boolean to check the truth value of its argument
|
41
|
+
# 2001-02-24 fl Added encoding/Unicode/SafeTransport patches
|
42
|
+
# 2001-02-26 fl Added compare support to wrappers (0.9.9/1.0b1)
|
43
|
+
# 2001-03-28 fl Make sure response tuple is a singleton
|
44
|
+
# 2001-03-29 fl Don't require empty params element (from Nicholas Riley)
|
45
|
+
# 2001-06-10 fl Folded in _xmlrpclib accelerator support (1.0b2)
|
46
|
+
# 2001-08-20 fl Base xmlrpclib.Error on built-in Exception (from Paul Prescod)
|
47
|
+
# 2001-09-03 fl Allow Transport subclass to override getparser
|
48
|
+
# 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup)
|
49
|
+
# 2001-10-01 fl Remove containers from memo cache when done with them
|
50
|
+
# 2001-10-01 fl Use faster escape method (80% dumps speedup)
|
51
|
+
# 2001-10-02 fl More dumps microtuning
|
52
|
+
# 2001-10-04 fl Make sure import expat gets a parser (from Guido van Rossum)
|
53
|
+
# 2001-10-10 sm Allow long ints to be passed as ints if they don't overflow
|
54
|
+
# 2001-10-17 sm Test for int and long overflow (allows use on 64-bit systems)
|
55
|
+
# 2001-11-12 fl Use repr() to marshal doubles (from Paul Felix)
|
56
|
+
# 2002-03-17 fl Avoid buffered read when possible (from James Rucker)
|
57
|
+
# 2002-04-07 fl Added pythondoc comments
|
58
|
+
# 2002-04-16 fl Added __str__ methods to datetime/binary wrappers
|
59
|
+
# 2002-05-15 fl Added error constants (from Andrew Kuchling)
|
60
|
+
# 2002-06-27 fl Merged with Python CVS version
|
61
|
+
# 2002-10-22 fl Added basic authentication (based on code from Phillip Eby)
|
62
|
+
# 2003-01-22 sm Add support for the bool type
|
63
|
+
# 2003-02-27 gvr Remove apply calls
|
64
|
+
# 2003-04-24 sm Use cStringIO if available
|
65
|
+
# 2003-04-25 ak Add support for nil
|
66
|
+
# 2003-06-15 gn Add support for time.struct_time
|
67
|
+
# 2003-07-12 gp Correct marshalling of Faults
|
68
|
+
# 2003-10-31 mvl Add multicall support
|
69
|
+
# 2004-08-20 mvl Bump minimum supported Python version to 2.1
|
70
|
+
#
|
71
|
+
# Copyright (c) 1999-2002 by Secret Labs AB.
|
72
|
+
# Copyright (c) 1999-2002 by Fredrik Lundh.
|
73
|
+
#
|
74
|
+
# info@pythonware.com
|
75
|
+
# http://www.pythonware.com
|
76
|
+
#
|
77
|
+
# --------------------------------------------------------------------
|
78
|
+
# The XML-RPC client interface is
|
79
|
+
#
|
80
|
+
# Copyright (c) 1999-2002 by Secret Labs AB
|
81
|
+
# Copyright (c) 1999-2002 by Fredrik Lundh
|
82
|
+
#
|
83
|
+
# By obtaining, using, and/or copying this software and/or its
|
84
|
+
# associated documentation, you agree that you have read, understood,
|
85
|
+
# and will comply with the following terms and conditions:
|
86
|
+
#
|
87
|
+
# Permission to use, copy, modify, and distribute this software and
|
88
|
+
# its associated documentation for any purpose and without fee is
|
89
|
+
# hereby granted, provided that the above copyright notice appears in
|
90
|
+
# all copies, and that both that copyright notice and this permission
|
91
|
+
# notice appear in supporting documentation, and that the name of
|
92
|
+
# Secret Labs AB or the author not be used in advertising or publicity
|
93
|
+
# pertaining to distribution of the software without specific, written
|
94
|
+
# prior permission.
|
95
|
+
#
|
96
|
+
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
|
97
|
+
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
|
98
|
+
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
|
99
|
+
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
100
|
+
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
101
|
+
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
102
|
+
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
103
|
+
# OF THIS SOFTWARE.
|
104
|
+
# --------------------------------------------------------------------
|
105
|
+
|
106
|
+
#
|
107
|
+
# things to look into some day:
|
108
|
+
|
109
|
+
# TODO: sort out True/False/boolean issues for Python 2.3
|
110
|
+
|
111
|
+
"""
|
112
|
+
An XML-RPC client interface for Python.
|
113
|
+
|
114
|
+
The marshalling and response parser code can also be used to
|
115
|
+
implement XML-RPC servers.
|
116
|
+
|
117
|
+
Exported exceptions:
|
118
|
+
|
119
|
+
Error Base class for client errors
|
120
|
+
ProtocolError Indicates an HTTP protocol error
|
121
|
+
ResponseError Indicates a broken response package
|
122
|
+
Fault Indicates an XML-RPC fault package
|
123
|
+
|
124
|
+
Exported classes:
|
125
|
+
|
126
|
+
ServerProxy Represents a logical connection to an XML-RPC server
|
127
|
+
|
128
|
+
MultiCall Executor of boxcared xmlrpc requests
|
129
|
+
Boolean boolean wrapper to generate a "boolean" XML-RPC value
|
130
|
+
DateTime dateTime wrapper for an ISO 8601 string or time tuple or
|
131
|
+
localtime integer value to generate a "dateTime.iso8601"
|
132
|
+
XML-RPC value
|
133
|
+
Binary binary data wrapper
|
134
|
+
|
135
|
+
SlowParser Slow but safe standard parser (based on xmllib)
|
136
|
+
Marshaller Generate an XML-RPC params chunk from a Python data structure
|
137
|
+
Unmarshaller Unmarshal an XML-RPC response from incoming XML event message
|
138
|
+
Transport Handles an HTTP transaction to an XML-RPC server
|
139
|
+
SafeTransport Handles an HTTPS transaction to an XML-RPC server
|
140
|
+
|
141
|
+
Exported constants:
|
142
|
+
|
143
|
+
True
|
144
|
+
False
|
145
|
+
|
146
|
+
Exported functions:
|
147
|
+
|
148
|
+
boolean Convert any Python value to an XML-RPC boolean
|
149
|
+
getparser Create instance of the fastest available parser & attach
|
150
|
+
to an unmarshalling object
|
151
|
+
dumps Convert an argument tuple or a Fault instance to an XML-RPC
|
152
|
+
request (or response, if the methodresponse option is used).
|
153
|
+
loads Convert an XML-RPC packet to unmarshalled data plus a method
|
154
|
+
name (None if not present).
|
155
|
+
"""
|
156
|
+
|
157
|
+
import re, string, time, operator
|
158
|
+
|
159
|
+
from types import *
|
160
|
+
|
161
|
+
# --------------------------------------------------------------------
|
162
|
+
# Internal stuff
|
163
|
+
|
164
|
+
try:
|
165
|
+
unicode
|
166
|
+
except NameError:
|
167
|
+
unicode = None # unicode support not available
|
168
|
+
|
169
|
+
try:
|
170
|
+
import datetime
|
171
|
+
except ImportError:
|
172
|
+
datetime = None
|
173
|
+
|
174
|
+
try:
|
175
|
+
_bool_is_builtin = False.__class__.__name__ == "bool"
|
176
|
+
except NameError:
|
177
|
+
_bool_is_builtin = 0
|
178
|
+
|
179
|
+
def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search):
|
180
|
+
# decode non-ascii string (if possible)
|
181
|
+
if unicode and encoding and is8bit(data):
|
182
|
+
data = unicode(data, encoding)
|
183
|
+
return data
|
184
|
+
|
185
|
+
def escape(s, replace=string.replace):
|
186
|
+
s = replace(s, "&", "&amp;")
|
187
|
+
s = replace(s, "<", "&lt;")
|
188
|
+
return replace(s, ">", "&gt;",)
|
189
|
+
|
190
|
+
if unicode:
|
191
|
+
def _stringify(string):
|
192
|
+
# convert to 7-bit ascii if possible
|
193
|
+
try:
|
194
|
+
return string.encode("ascii")
|
195
|
+
except UnicodeError:
|
196
|
+
return string
|
197
|
+
else:
|
198
|
+
def _stringify(string):
|
199
|
+
return string
|
200
|
+
|
201
|
+
__version__ = "1.0.1"
|
202
|
+
|
203
|
+
# xmlrpc integer limits
|
204
|
+
MAXINT = 2L**31-1
|
205
|
+
MININT = -2L**31
|
206
|
+
|
207
|
+
# --------------------------------------------------------------------
|
208
|
+
# Error constants (from Dan Libby's specification at
|
209
|
+
# http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php)
|
210
|
+
|
211
|
+
# Ranges of errors
|
212
|
+
PARSE_ERROR = -32700
|
213
|
+
SERVER_ERROR = -32600
|
214
|
+
APPLICATION_ERROR = -32500
|
215
|
+
SYSTEM_ERROR = -32400
|
216
|
+
TRANSPORT_ERROR = -32300
|
217
|
+
|
218
|
+
# Specific errors
|
219
|
+
NOT_WELLFORMED_ERROR = -32700
|
220
|
+
UNSUPPORTED_ENCODING = -32701
|
221
|
+
INVALID_ENCODING_CHAR = -32702
|
222
|
+
INVALID_XMLRPC = -32600
|
223
|
+
METHOD_NOT_FOUND = -32601
|
224
|
+
INVALID_METHOD_PARAMS = -32602
|
225
|
+
INTERNAL_ERROR = -32603
|
226
|
+
|
227
|
+
# --------------------------------------------------------------------
|
228
|
+
# Exceptions
|
229
|
+
|
230
|
+
##
|
231
|
+
# Base class for all kinds of client-side errors.
|
232
|
+
|
233
|
+
class Error(Exception):
|
234
|
+
"""Base class for client errors."""
|
235
|
+
def __str__(self):
|
236
|
+
return repr(self)
|
237
|
+
|
238
|
+
##
|
239
|
+
# Indicates an HTTP-level protocol error. This is raised by the HTTP
|
240
|
+
# transport layer, if the server returns an error code other than 200
|
241
|
+
# (OK).
|
242
|
+
#
|
243
|
+
# @param url The target URL.
|
244
|
+
# @param errcode The HTTP error code.
|
245
|
+
# @param errmsg The HTTP error message.
|
246
|
+
# @param headers The HTTP header dictionary.
|
247
|
+
|
248
|
+
class ProtocolError(Error):
|
249
|
+
"""Indicates an HTTP protocol error."""
|
250
|
+
def __init__(self, url, errcode, errmsg, headers):
|
251
|
+
Error.__init__(self)
|
252
|
+
self.url = url
|
253
|
+
self.errcode = errcode
|
254
|
+
self.errmsg = errmsg
|
255
|
+
self.headers = headers
|
256
|
+
def __repr__(self):
|
257
|
+
return (
|
258
|
+
"<ProtocolError for %s: %s %s>" %
|
259
|
+
(self.url, self.errcode, self.errmsg)
|
260
|
+
)
|
261
|
+
|
262
|
+
##
|
263
|
+
# Indicates a broken XML-RPC response package. This exception is
|
264
|
+
# raised by the unmarshalling layer, if the XML-RPC response is
|
265
|
+
# malformed.
|
266
|
+
|
267
|
+
class ResponseError(Error):
|
268
|
+
"""Indicates a broken response package."""
|
269
|
+
pass
|
270
|
+
|
271
|
+
##
|
272
|
+
# Indicates an XML-RPC fault response package. This exception is
|
273
|
+
# raised by the unmarshalling layer, if the XML-RPC response contains
|
274
|
+
# a fault string. This exception can also used as a class, to
|
275
|
+
# generate a fault XML-RPC message.
|
276
|
+
#
|
277
|
+
# @param faultCode The XML-RPC fault code.
|
278
|
+
# @param faultString The XML-RPC fault string.
|
279
|
+
|
280
|
+
class Fault(Error):
|
281
|
+
"""Indicates an XML-RPC fault package."""
|
282
|
+
def __init__(self, faultCode, faultString, **extra):
|
283
|
+
Error.__init__(self)
|
284
|
+
self.faultCode = faultCode
|
285
|
+
self.faultString = faultString
|
286
|
+
def __repr__(self):
|
287
|
+
return (
|
288
|
+
"<Fault %s: %s>" %
|
289
|
+
(self.faultCode, repr(self.faultString))
|
290
|
+
)
|
291
|
+
|
292
|
+
# --------------------------------------------------------------------
|
293
|
+
# Special values
|
294
|
+
|
295
|
+
##
|
296
|
+
# Wrapper for XML-RPC boolean values. Use the xmlrpclib.True and
|
297
|
+
# xmlrpclib.False constants, or the xmlrpclib.boolean() function, to
|
298
|
+
# generate boolean XML-RPC values.
|
299
|
+
#
|
300
|
+
# @param value A boolean value. Any true value is interpreted as True,
|
301
|
+
# all other values are interpreted as False.
|
302
|
+
|
303
|
+
if _bool_is_builtin:
|
304
|
+
boolean = Boolean = bool
|
305
|
+
# to avoid breaking code which references xmlrpclib.{True,False}
|
306
|
+
True, False = True, False
|
307
|
+
else:
|
308
|
+
class Boolean:
|
309
|
+
"""Boolean-value wrapper.
|
310
|
+
|
311
|
+
Use True or False to generate a "boolean" XML-RPC value.
|
312
|
+
"""
|
313
|
+
|
314
|
+
def __init__(self, value = 0):
|
315
|
+
self.value = operator.truth(value)
|
316
|
+
|
317
|
+
def encode(self, out):
|
318
|
+
out.write("<value><boolean>%d</boolean></value>\n" % self.value)
|
319
|
+
|
320
|
+
def __cmp__(self, other):
|
321
|
+
if isinstance(other, Boolean):
|
322
|
+
other = other.value
|
323
|
+
return cmp(self.value, other)
|
324
|
+
|
325
|
+
def __repr__(self):
|
326
|
+
if self.value:
|
327
|
+
return "<Boolean True at %x>" % id(self)
|
328
|
+
else:
|
329
|
+
return "<Boolean False at %x>" % id(self)
|
330
|
+
|
331
|
+
def __int__(self):
|
332
|
+
return self.value
|
333
|
+
|
334
|
+
@bob # dole
|
335
|
+
def __nonzero__(self):
|
336
|
+
return self.value
|
337
|
+
|
338
|
+
True, False = Boolean(1), Boolean(0)
|
339
|
+
|
340
|
+
##
|
341
|
+
# Map true or false value to XML-RPC boolean values.
|
342
|
+
#
|
343
|
+
# @def boolean(value)
|
344
|
+
# @param value A boolean value. Any true value is mapped to True,
|
345
|
+
# all other values are mapped to False.
|
346
|
+
# @return xmlrpclib.True or xmlrpclib.False.
|
347
|
+
# @see Boolean
|
348
|
+
# @see True
|
349
|
+
# @see False
|
350
|
+
|
351
|
+
def boolean(value, _truefalse=(False, True)):
|
352
|
+
"""Convert any Python value to XML-RPC 'boolean'."""
|
353
|
+
return _truefalse[operator.truth(value)]
|
354
|
+
|
355
|
+
##
|
356
|
+
# Wrapper for XML-RPC DateTime values. This converts a time value to
|
357
|
+
# the format used by XML-RPC.
|
358
|
+
# <p>
|
359
|
+
# The value can be given as a string in the format
|
360
|
+
# "yyyymmddThh:mm:ss", as a 9-item time tuple (as returned by
|
361
|
+
# time.localtime()), or an integer value (as returned by time.time()).
|
362
|
+
# The wrapper uses time.localtime() to convert an integer to a time
|
363
|
+
# tuple.
|
364
|
+
#
|
365
|
+
# @param value The time, given as an ISO 8601 string, a time
|
366
|
+
# tuple, or a integer time value.
|
367
|
+
|
368
|
+
class DateTime:
|
369
|
+
"""DateTime wrapper for an ISO 8601 string or time tuple or
|
370
|
+
localtime integer value to generate 'dateTime.iso8601' XML-RPC
|
371
|
+
value.
|
372
|
+
"""
|
373
|
+
|
374
|
+
def __init__(self, value=0):
|
375
|
+
if not isinstance(value, StringType):
|
376
|
+
if datetime and isinstance(value, datetime.datetime):
|
377
|
+
self.value = value.strftime("%Y%m%dT%H:%M:%S")
|
378
|
+
return
|
379
|
+
if datetime and isinstance(value, datetime.date):
|
380
|
+
self.value = value.strftime("%Y%m%dT%H:%M:%S")
|
381
|
+
return
|
382
|
+
if datetime and isinstance(value, datetime.time):
|
383
|
+
today = datetime.datetime.now().strftime("%Y%m%d")
|
384
|
+
self.value = value.strftime(today+"T%H:%M:%S")
|
385
|
+
return
|
386
|
+
if not isinstance(value, (TupleType, time.struct_time)):
|
387
|
+
if value == 0:
|
388
|
+
value = time.time()
|
389
|
+
value = time.localtime(value)
|
390
|
+
value = time.strftime("%Y%m%dT%H:%M:%S", value)
|
391
|
+
self.value = value
|
392
|
+
|
393
|
+
def __cmp__(self, other):
|
394
|
+
if isinstance(other, DateTime):
|
395
|
+
other = other.value
|
396
|
+
return cmp(self.value, other)
|
397
|
+
|
398
|
+
##
|
399
|
+
# Get date/time value.
|
400
|
+
#
|
401
|
+
# @return Date/time value, as an ISO 8601 string.
|
402
|
+
|
403
|
+
def __str__(self):
|
404
|
+
return self.value
|
405
|
+
|
406
|
+
def __repr__(self):
|
407
|
+
return "<DateTime %s at %x>" % (repr(self.value), id(self))
|
408
|
+
|
409
|
+
def decode(self, data):
|
410
|
+
data = str(data)
|
411
|
+
self.value = string.strip(data)
|
412
|
+
|
413
|
+
def encode(self, out):
|
414
|
+
out.write("<value><dateTime.iso8601>")
|
415
|
+
out.write(self.value)
|
416
|
+
out.write("</dateTime.iso8601></value>\n")
|
417
|
+
|
418
|
+
def _datetime(data):
|
419
|
+
# decode xml element contents into a DateTime structure.
|
420
|
+
value = DateTime()
|
421
|
+
value.decode(data)
|
422
|
+
return value
|
423
|
+
|
424
|
+
def _datetime_type(data):
|
425
|
+
t = time.strptime(data, "%Y%m%dT%H:%M:%S")
|
426
|
+
return datetime.datetime(*tuple(t)[:6])
|
427
|
+
|
428
|
+
##
|
429
|
+
# Wrapper for binary data. This can be used to transport any kind
|
430
|
+
# of binary data over XML-RPC, using BASE64 encoding.
|
431
|
+
#
|
432
|
+
# @param data An 8-bit string containing arbitrary data.
|
433
|
+
|
434
|
+
import base64
|
435
|
+
try:
|
436
|
+
import cStringIO as StringIO
|
437
|
+
except ImportError:
|
438
|
+
import StringIO
|
439
|
+
|
440
|
+
class Binary:
|
441
|
+
"""Wrapper for binary data."""
|
442
|
+
|
443
|
+
def __init__(self, data=None):
|
444
|
+
self.data = data
|
445
|
+
|
446
|
+
##
|
447
|
+
# Get buffer contents.
|
448
|
+
#
|
449
|
+
# @return Buffer contents, as an 8-bit string.
|
450
|
+
|
451
|
+
def __str__(self):
|
452
|
+
return self.data or ""
|
453
|
+
|
454
|
+
def __cmp__(self, other):
|
455
|
+
if isinstance(other, Binary):
|
456
|
+
other = other.data
|
457
|
+
return cmp(self.data, other)
|
458
|
+
|
459
|
+
def decode(self, data):
|
460
|
+
self.data = base64.decodestring(data)
|
461
|
+
|
462
|
+
def encode(self, out):
|
463
|
+
out.write("<value><base64>\n")
|
464
|
+
base64.encode(StringIO.StringIO(self.data), out)
|
465
|
+
out.write("</base64></value>\n")
|
466
|
+
|
467
|
+
def _binary(data):
|
468
|
+
# decode xml element contents into a Binary structure
|
469
|
+
value = Binary()
|
470
|
+
value.decode(data)
|
471
|
+
return value
|
472
|
+
|
473
|
+
WRAPPERS = (DateTime, Binary)
|
474
|
+
if not _bool_is_builtin:
|
475
|
+
WRAPPERS = WRAPPERS + (Boolean,)
|
476
|
+
|
477
|
+
# --------------------------------------------------------------------
|
478
|
+
# XML parsers
|
479
|
+
|
480
|
+
try:
|
481
|
+
# optional xmlrpclib accelerator
|
482
|
+
import _xmlrpclib
|
483
|
+
FastParser = _xmlrpclib.Parser
|
484
|
+
FastUnmarshaller = _xmlrpclib.Unmarshaller
|
485
|
+
except (AttributeError, ImportError):
|
486
|
+
FastParser = FastUnmarshaller = None
|
487
|
+
|
488
|
+
try:
|
489
|
+
import _xmlrpclib
|
490
|
+
FastMarshaller = _xmlrpclib.Marshaller
|
491
|
+
except (AttributeError, ImportError):
|
492
|
+
FastMarshaller = None
|
493
|
+
|
494
|
+
#
|
495
|
+
# the SGMLOP parser is about 15x faster than Python's builtin
|
496
|
+
# XML parser. SGMLOP sources can be downloaded from:
|
497
|
+
#
|
498
|
+
# http://www.pythonware.com/products/xml/sgmlop.htm
|
499
|
+
#
|
500
|
+
|
501
|
+
try:
|
502
|
+
import sgmlop
|
503
|
+
if not hasattr(sgmlop, "XMLParser"):
|
504
|
+
raise ImportError
|
505
|
+
except ImportError:
|
506
|
+
SgmlopParser = None # sgmlop accelerator not available
|
507
|
+
else:
|
508
|
+
class SgmlopParser:
|
509
|
+
def __init__(self, target):
|
510
|
+
|
511
|
+
# setup callbacks
|
512
|
+
self.finish_starttag = target.start
|
513
|
+
self.finish_endtag = target.end
|
514
|
+
self.handle_data = target.data
|
515
|
+
self.handle_xml = target.xml
|
516
|
+
|
517
|
+
# activate parser
|
518
|
+
self.parser = sgmlop.XMLParser()
|
519
|
+
self.parser.register(self)
|
520
|
+
self.feed = self.parser.feed
|
521
|
+
self.entity = {
|
522
|
+
"amp": "&", "gt": ">", "lt": "<",
|
523
|
+
"apos": "'", "quot": '"'
|
524
|
+
}
|
525
|
+
|
526
|
+
def close(self):
|
527
|
+
try:
|
528
|
+
self.parser.close()
|
529
|
+
finally:
|
530
|
+
self.parser = self.feed = None # nuke circular reference
|
531
|
+
|
532
|
+
def handle_proc(self, tag, attr):
|
533
|
+
m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr)
|
534
|
+
if m:
|
535
|
+
self.handle_xml(m.group(1), 1)
|
536
|
+
|
537
|
+
def handle_entityref(self, entity):
|
538
|
+
# <string> entity
|
539
|
+
try:
|
540
|
+
self.handle_data(self.entity[entity])
|
541
|
+
except KeyError:
|
542
|
+
self.handle_data("&%s;" % entity)
|
543
|
+
|
544
|
+
try:
|
545
|
+
from xml.parsers import expat
|
546
|
+
if not hasattr(expat, "ParserCreate"):
|
547
|
+
raise ImportError
|
548
|
+
except ImportError:
|
549
|
+
ExpatParser = None # expat not available
|
550
|
+
else:
|
551
|
+
class ExpatParser:
|
552
|
+
# fast expat parser for Python 2.0 and later. this is about
|
553
|
+
# 50% slower than sgmlop, on roundtrip testing
|
554
|
+
def __init__(self, target):
|
555
|
+
self._parser = parser = expat.ParserCreate(None, None)
|
556
|
+
self._target = target
|
557
|
+
parser.StartElementHandler = target.start
|
558
|
+
parser.EndElementHandler = target.end
|
559
|
+
parser.CharacterDataHandler = target.data
|
560
|
+
encoding = None
|
561
|
+
if not parser.returns_unicode:
|
562
|
+
encoding = "utf-8"
|
563
|
+
target.xml(encoding, None)
|
564
|
+
|
565
|
+
def feed(self, data):
|
566
|
+
self._parser.Parse(data, 0)
|
567
|
+
|
568
|
+
def close(self):
|
569
|
+
self._parser.Parse("", 1) # end of data
|
570
|
+
del self._target, self._parser # get rid of circular references
|
571
|
+
|
572
|
+
class SlowParser:
|
573
|
+
"""Default XML parser (based on xmllib.XMLParser)."""
|
574
|
+
# this is about 10 times slower than sgmlop, on roundtrip
|
575
|
+
# testing.
|
576
|
+
def __init__(self, target):
|
577
|
+
import xmllib # lazy subclassing (!)
|
578
|
+
if xmllib.XMLParser not in SlowParser.__bases__:
|
579
|
+
SlowParser.__bases__ = (xmllib.XMLParser,)
|
580
|
+
self.handle_xml = target.xml
|
581
|
+
self.unknown_starttag = target.start
|
582
|
+
self.handle_data = target.data
|
583
|
+
self.handle_cdata = target.data
|
584
|
+
self.unknown_endtag = target.end
|
585
|
+
try:
|
586
|
+
xmllib.XMLParser.__init__(self, accept_utf8=1)
|
587
|
+
except TypeError:
|
588
|
+
xmllib.XMLParser.__init__(self) # pre-2.0
|
589
|
+
|
590
|
+
# --------------------------------------------------------------------
|
591
|
+
# XML-RPC marshalling and unmarshalling code
|
592
|
+
|
593
|
+
##
|
594
|
+
# XML-RPC marshaller.
|
595
|
+
#
|
596
|
+
# @param encoding Default encoding for 8-bit strings. The default
|
597
|
+
# value is None (interpreted as UTF-8).
|
598
|
+
# @see dumps
|
599
|
+
|
600
|
+
class Marshaller:
|
601
|
+
"""Generate an XML-RPC params chunk from a Python data structure.
|
602
|
+
|
603
|
+
Create a Marshaller instance for each set of parameters, and use
|
604
|
+
the "dumps" method to convert your data (represented as a tuple)
|
605
|
+
to an XML-RPC params chunk. To write a fault response, pass a
|
606
|
+
Fault instance instead. You may prefer to use the "dumps" module
|
607
|
+
function for this purpose.
|
608
|
+
"""
|
609
|
+
|
610
|
+
# by the way, if you don't understand what's going on in here,
|
611
|
+
# that's perfectly ok.
|
612
|
+
|
613
|
+
def __init__(self, encoding=None, allow_none=0):
|
614
|
+
self.memo = {}
|
615
|
+
self.data = None
|
616
|
+
self.encoding = encoding
|
617
|
+
self.allow_none = allow_none
|
618
|
+
|
619
|
+
dispatch = {}
|
620
|
+
|
621
|
+
def dumps(self, values):
|
622
|
+
out = []
|
623
|
+
write = out.append
|
624
|
+
dump = self.__dump
|
625
|
+
if isinstance(values, Fault):
|
626
|
+
# fault instance
|
627
|
+
write("<fault>\n")
|
628
|
+
dump({'faultCode': values.faultCode,
|
629
|
+
'faultString': values.faultString},
|
630
|
+
write)
|
631
|
+
write("</fault>\n")
|
632
|
+
else:
|
633
|
+
# parameter block
|
634
|
+
# FIXME: the xml-rpc specification allows us to leave out
|
635
|
+
# the entire <params> block if there are no parameters.
|
636
|
+
# however, changing this may break older code (including
|
637
|
+
# old versions of xmlrpclib.py), so this is better left as
|
638
|
+
# is for now. See @XMLRPC3 for more information. /F
|
639
|
+
write("<params>\n")
|
640
|
+
for v in values:
|
641
|
+
write("<param>\n")
|
642
|
+
dump(v, write)
|
643
|
+
write("</param>\n")
|
644
|
+
write("</params>\n")
|
645
|
+
result = string.join(out, "")
|
646
|
+
return result
|
647
|
+
|
648
|
+
def __dump(self, value, write):
|
649
|
+
try:
|
650
|
+
f = self.dispatch[type(value)]
|
651
|
+
except KeyError:
|
652
|
+
raise TypeError, "cannot marshal %s objects" % type(value)
|
653
|
+
else:
|
654
|
+
f(self, value, write)
|
655
|
+
|
656
|
+
def dump_nil (self, value, write):
|
657
|
+
if not self.allow_none:
|
658
|
+
raise TypeError, "cannot marshal None unless allow_none is enabled"
|
659
|
+
write("<value><nil/></value>")
|
660
|
+
dispatch[NoneType] = dump_nil
|
661
|
+
|
662
|
+
def dump_int(self, value, write):
|
663
|
+
# in case ints are > 32 bits
|
664
|
+
if value > MAXINT or value < MININT:
|
665
|
+
raise OverflowError, "int exceeds XML-RPC limits"
|
666
|
+
write("<value><int>")
|
667
|
+
write(str(value))
|
668
|
+
write("</int></value>\n")
|
669
|
+
dispatch[IntType] = dump_int
|
670
|
+
|
671
|
+
if _bool_is_builtin:
|
672
|
+
def dump_bool(self, value, write):
|
673
|
+
write("<value><boolean>")
|
674
|
+
write(value and "1" or "0")
|
675
|
+
write("</boolean></value>\n")
|
676
|
+
dispatch[bool] = dump_bool
|
677
|
+
|
678
|
+
def dump_long(self, value, write):
|
679
|
+
if value > MAXINT or value < MININT:
|
680
|
+
raise OverflowError, "long int exceeds XML-RPC limits"
|
681
|
+
write("<value><int>")
|
682
|
+
write(str(int(value)))
|
683
|
+
write("</int></value>\n")
|
684
|
+
dispatch[LongType] = dump_long
|
685
|
+
|
686
|
+
def dump_double(self, value, write):
|
687
|
+
write("<value><double>")
|
688
|
+
write(repr(value))
|
689
|
+
write("</double></value>\n")
|
690
|
+
dispatch[FloatType] = dump_double
|
691
|
+
|
692
|
+
def dump_string(self, value, write, escape=escape):
|
693
|
+
write("<value><string>")
|
694
|
+
write(escape(value))
|
695
|
+
write("</string></value>\n")
|
696
|
+
dispatch[StringType] = dump_string
|
697
|
+
|
698
|
+
if unicode:
|
699
|
+
def dump_unicode(self, value, write, escape=escape):
|
700
|
+
value = value.encode(self.encoding)
|
701
|
+
write("<value><string>")
|
702
|
+
write(escape(value))
|
703
|
+
write("</string></value>\n")
|
704
|
+
dispatch[UnicodeType] = dump_unicode
|
705
|
+
|
706
|
+
def dump_array(self, value, write):
|
707
|
+
i = id(value)
|
708
|
+
if self.memo.has_key(i):
|
709
|
+
raise TypeError, "cannot marshal recursive sequences"
|
710
|
+
self.memo[i] = None
|
711
|
+
dump = self.__dump
|
712
|
+
write("<value><array><data>\n")
|
713
|
+
for v in value:
|
714
|
+
dump(v, write)
|
715
|
+
write("</data></array></value>\n")
|
716
|
+
del self.memo[i]
|
717
|
+
dispatch[TupleType] = dump_array
|
718
|
+
dispatch[ListType] = dump_array
|
719
|
+
|
720
|
+
def dump_struct(self, value, write, escape=escape):
|
721
|
+
i = id(value)
|
722
|
+
if self.memo.has_key(i):
|
723
|
+
raise TypeError, "cannot marshal recursive dictionaries"
|
724
|
+
self.memo[i] = None
|
725
|
+
dump = self.__dump
|
726
|
+
write("<value><struct>\n")
|
727
|
+
for k, v in value.items():
|
728
|
+
write("<member>\n")
|
729
|
+
if type(k) is not StringType:
|
730
|
+
if unicode and type(k) is UnicodeType:
|
731
|
+
k = k.encode(self.encoding)
|
732
|
+
else:
|
733
|
+
raise TypeError, "dictionary key must be string"
|
734
|
+
write("<name>%s</name>\n" % escape(k))
|
735
|
+
dump(v, write)
|
736
|
+
write("</member>\n")
|
737
|
+
write("</struct></value>\n")
|
738
|
+
del self.memo[i]
|
739
|
+
dispatch[DictType] = dump_struct
|
740
|
+
|
741
|
+
if datetime:
|
742
|
+
def dump_datetime(self, value, write):
|
743
|
+
write("<value><dateTime.iso8601>")
|
744
|
+
write(value.strftime("%Y%m%dT%H:%M:%S"))
|
745
|
+
write("</dateTime.iso8601></value>\n")
|
746
|
+
dispatch[datetime.datetime] = dump_datetime
|
747
|
+
|
748
|
+
def dump_date(self, value, write):
|
749
|
+
write("<value><dateTime.iso8601>")
|
750
|
+
write(value.strftime("%Y%m%dT00:00:00"))
|
751
|
+
write("</dateTime.iso8601></value>\n")
|
752
|
+
dispatch[datetime.date] = dump_date
|
753
|
+
|
754
|
+
def dump_time(self, value, write):
|
755
|
+
write("<value><dateTime.iso8601>")
|
756
|
+
write(datetime.datetime.now().date().strftime("%Y%m%dT"))
|
757
|
+
write(value.strftime("%H:%M:%S"))
|
758
|
+
write("</dateTime.iso8601></value>\n")
|
759
|
+
dispatch[datetime.time] = dump_time
|
760
|
+
|
761
|
+
def dump_instance(self, value, write):
|
762
|
+
# check for special wrappers
|
763
|
+
if value.__class__ in WRAPPERS:
|
764
|
+
self.write = write
|
765
|
+
value.encode(self)
|
766
|
+
del self.write
|
767
|
+
else:
|
768
|
+
# store instance attributes as a struct (really?)
|
769
|
+
self.dump_struct(value.__dict__, write)
|
770
|
+
dispatch[InstanceType] = dump_instance
|
771
|
+
|
772
|
+
##
|
773
|
+
# XML-RPC unmarshaller.
|
774
|
+
#
|
775
|
+
# @see loads
|
776
|
+
|
777
|
+
class Unmarshaller:
|
778
|
+
"""Unmarshal an XML-RPC response, based on incoming XML event
|
779
|
+
messages (start, data, end). Call close() to get the resulting
|
780
|
+
data structure.
|
781
|
+
|
782
|
+
Note that this reader is fairly tolerant, and gladly accepts bogus
|
783
|
+
XML-RPC data without complaining (but not bogus XML).
|
784
|
+
"""
|
785
|
+
|
786
|
+
# and again, if you don't understand what's going on in here,
|
787
|
+
# that's perfectly ok.
|
788
|
+
|
789
|
+
def __init__(self, use_datetime=0):
|
790
|
+
self._type = None
|
791
|
+
self._stack = []
|
792
|
+
self._marks = []
|
793
|
+
self._data = []
|
794
|
+
self._methodname = None
|
795
|
+
self._encoding = "utf-8"
|
796
|
+
self.append = self._stack.append
|
797
|
+
self._use_datetime = use_datetime
|
798
|
+
if use_datetime and not datetime:
|
799
|
+
raise ValueError, "the datetime module is not available"
|
800
|
+
|
801
|
+
def close(self):
|
802
|
+
# return response tuple and target method
|
803
|
+
if self._type is None or self._marks:
|
804
|
+
raise ResponseError()
|
805
|
+
if self._type == "fault":
|
806
|
+
raise Fault(**self._stack[0])
|
807
|
+
return tuple(self._stack)
|
808
|
+
|
809
|
+
def getmethodname(self):
|
810
|
+
return self._methodname
|
811
|
+
|
812
|
+
#
|
813
|
+
# event handlers
|
814
|
+
|
815
|
+
def xml(self, encoding, standalone):
|
816
|
+
self._encoding = encoding
|
817
|
+
# FIXME: assert standalone == 1 ???
|
818
|
+
|
819
|
+
def start(self, tag, attrs):
|
820
|
+
# prepare to handle this element
|
821
|
+
if tag == "array" or tag == "struct":
|
822
|
+
self._marks.append(len(self._stack))
|
823
|
+
self._data = []
|
824
|
+
self._value = (tag == "value")
|
825
|
+
|
826
|
+
def data(self, text):
|
827
|
+
self._data.append(text)
|
828
|
+
|
829
|
+
def end(self, tag, join=string.join):
|
830
|
+
# call the appropriate end tag handler
|
831
|
+
try:
|
832
|
+
f = self.dispatch[tag]
|
833
|
+
except KeyError:
|
834
|
+
pass # unknown tag ?
|
835
|
+
else:
|
836
|
+
return f(self, join(self._data, ""))
|
837
|
+
|
838
|
+
#
|
839
|
+
# accelerator support
|
840
|
+
|
841
|
+
def end_dispatch(self, tag, data):
|
842
|
+
# dispatch data
|
843
|
+
try:
|
844
|
+
f = self.dispatch[tag]
|
845
|
+
except KeyError:
|
846
|
+
pass # unknown tag ?
|
847
|
+
else:
|
848
|
+
return f(self, data)
|
849
|
+
|
850
|
+
#
|
851
|
+
# element decoders
|
852
|
+
|
853
|
+
dispatch = {}
|
854
|
+
|
855
|
+
def end_nil (self, data):
|
856
|
+
self.append(None)
|
857
|
+
self._value = 0
|
858
|
+
dispatch["nil"] = end_nil
|
859
|
+
|
860
|
+
def end_boolean(self, data):
|
861
|
+
if data == "0":
|
862
|
+
self.append(False)
|
863
|
+
elif data == "1":
|
864
|
+
self.append(True)
|
865
|
+
else:
|
866
|
+
raise TypeError, "bad boolean value"
|
867
|
+
self._value = 0
|
868
|
+
dispatch["boolean"] = end_boolean
|
869
|
+
|
870
|
+
def end_int(self, data):
|
871
|
+
self.append(int(data))
|
872
|
+
self._value = 0
|
873
|
+
dispatch["i4"] = end_int
|
874
|
+
dispatch["int"] = end_int
|
875
|
+
|
876
|
+
def end_double(self, data):
|
877
|
+
self.append(float(data))
|
878
|
+
self._value = 0
|
879
|
+
dispatch["double"] = end_double
|
880
|
+
|
881
|
+
def end_string(self, data):
|
882
|
+
if self._encoding:
|
883
|
+
data = _decode(data, self._encoding)
|
884
|
+
self.append(_stringify(data))
|
885
|
+
self._value = 0
|
886
|
+
dispatch["string"] = end_string
|
887
|
+
dispatch["name"] = end_string # struct keys are always strings
|
888
|
+
|
889
|
+
def end_array(self, data):
|
890
|
+
mark = self._marks.pop()
|
891
|
+
# map arrays to Python lists
|
892
|
+
self._stack[mark:] = [self._stack[mark:]]
|
893
|
+
self._value = 0
|
894
|
+
dispatch["array"] = end_array
|
895
|
+
|
896
|
+
def end_struct(self, data):
|
897
|
+
mark = self._marks.pop()
|
898
|
+
# map structs to Python dictionaries
|
899
|
+
dict = {}
|
900
|
+
items = self._stack[mark:]
|
901
|
+
for i in range(0, len(items), 2):
|
902
|
+
dict[_stringify(items[i])] = items[i+1]
|
903
|
+
self._stack[mark:] = [dict]
|
904
|
+
self._value = 0
|
905
|
+
dispatch["struct"] = end_struct
|
906
|
+
|
907
|
+
def end_base64(self, data):
|
908
|
+
value = Binary()
|
909
|
+
value.decode(data)
|
910
|
+
self.append(value)
|
911
|
+
self._value = 0
|
912
|
+
dispatch["base64"] = end_base64
|
913
|
+
|
914
|
+
def end_dateTime(self, data):
|
915
|
+
value = DateTime()
|
916
|
+
value.decode(data)
|
917
|
+
if self._use_datetime:
|
918
|
+
value = _datetime_type(data)
|
919
|
+
self.append(value)
|
920
|
+
dispatch["dateTime.iso8601"] = end_dateTime
|
921
|
+
|
922
|
+
def end_value(self, data):
|
923
|
+
# if we stumble upon a value element with no internal
|
924
|
+
# elements, treat it as a string element
|
925
|
+
if self._value:
|
926
|
+
self.end_string(data)
|
927
|
+
dispatch["value"] = end_value
|
928
|
+
|
929
|
+
def end_params(self, data):
|
930
|
+
self._type = "params"
|
931
|
+
dispatch["params"] = end_params
|
932
|
+
|
933
|
+
def end_fault(self, data):
|
934
|
+
self._type = "fault"
|
935
|
+
dispatch["fault"] = end_fault
|
936
|
+
|
937
|
+
def end_methodName(self, data):
|
938
|
+
if self._encoding:
|
939
|
+
data = _decode(data, self._encoding)
|
940
|
+
self._methodname = data
|
941
|
+
self._type = "methodName" # no params
|
942
|
+
dispatch["methodName"] = end_methodName
|
943
|
+
|
944
|
+
## Multicall support
|
945
|
+
#
|
946
|
+
|
947
|
+
class _MultiCallMethod:
|
948
|
+
# some lesser magic to store calls made to a MultiCall object
|
949
|
+
# for batch execution
|
950
|
+
def __init__(self, call_list, name):
|
951
|
+
self.__call_list = call_list
|
952
|
+
self.__name = name
|
953
|
+
def __getattr__(self, name):
|
954
|
+
return _MultiCallMethod(self.__call_list, "%s.%s" % (self.__name, name))
|
955
|
+
def __call__(self, *args):
|
956
|
+
self.__call_list.append((self.__name, args))
|
957
|
+
|
958
|
+
class MultiCallIterator:
|
959
|
+
"""Iterates over the results of a multicall. Exceptions are
|
960
|
+
thrown in response to xmlrpc faults."""
|
961
|
+
|
962
|
+
def __init__(self, results):
|
963
|
+
self.results = results
|
964
|
+
|
965
|
+
def __getitem__(self, i):
|
966
|
+
item = self.results[i]
|
967
|
+
if type(item) == type({}):
|
968
|
+
raise Fault(item['faultCode'], item['faultString'])
|
969
|
+
elif type(item) == type([]):
|
970
|
+
return item[0]
|
971
|
+
else:
|
972
|
+
raise ValueError,\
|
973
|
+
"unexpected type in multicall result"
|
974
|
+
|
975
|
+
class MultiCall:
|
976
|
+
"""server -> a object used to boxcar method calls
|
977
|
+
|
978
|
+
server should be a ServerProxy object.
|
979
|
+
|
980
|
+
Methods can be added to the MultiCall using normal
|
981
|
+
method call syntax e.g.:
|
982
|
+
|
983
|
+
multicall = MultiCall(server_proxy)
|
984
|
+
multicall.add(2,3)
|
985
|
+
multicall.get_address("Guido")
|
986
|
+
|
987
|
+
To execute the multicall, call the MultiCall object e.g.:
|
988
|
+
|
989
|
+
add_result, address = multicall()
|
990
|
+
"""
|
991
|
+
|
992
|
+
def __init__(self, server):
|
993
|
+
self.__server = server
|
994
|
+
self.__call_list = []
|
995
|
+
|
996
|
+
def __repr__(self):
|
997
|
+
return "<MultiCall at %x>" % id(self)
|
998
|
+
|
999
|
+
__str__ = __repr__
|
1000
|
+
|
1001
|
+
def __getattr__(self, name):
|
1002
|
+
return _MultiCallMethod(self.__call_list, name)
|
1003
|
+
|
1004
|
+
def __call__(self):
|
1005
|
+
marshalled_list = []
|
1006
|
+
for name, args in self.__call_list:
|
1007
|
+
marshalled_list.append({'methodName' : name, 'params' : args})
|
1008
|
+
|
1009
|
+
return MultiCallIterator(self.__server.system.multicall(marshalled_list))
|
1010
|
+
|
1011
|
+
# --------------------------------------------------------------------
|
1012
|
+
# convenience functions
|
1013
|
+
|
1014
|
+
##
|
1015
|
+
# Create a parser object, and connect it to an unmarshalling instance.
|
1016
|
+
# This function picks the fastest available XML parser.
|
1017
|
+
#
|
1018
|
+
# return A (parser, unmarshaller) tuple.
|
1019
|
+
|
1020
|
+
def getparser(use_datetime=0):
|
1021
|
+
"""getparser() -> parser, unmarshaller
|
1022
|
+
|
1023
|
+
Create an instance of the fastest available parser, and attach it
|
1024
|
+
to an unmarshalling object. Return both objects.
|
1025
|
+
"""
|
1026
|
+
if use_datetime and not datetime:
|
1027
|
+
raise ValueError, "the datetime module is not available"
|
1028
|
+
if FastParser and FastUnmarshaller:
|
1029
|
+
if use_datetime:
|
1030
|
+
mkdatetime = _datetime_type
|
1031
|
+
else:
|
1032
|
+
mkdatetime = _datetime
|
1033
|
+
target = FastUnmarshaller(True, False, _binary, mkdatetime, Fault)
|
1034
|
+
parser = FastParser(target)
|
1035
|
+
else:
|
1036
|
+
target = Unmarshaller(use_datetime=use_datetime)
|
1037
|
+
if FastParser:
|
1038
|
+
parser = FastParser(target)
|
1039
|
+
elif SgmlopParser:
|
1040
|
+
parser = SgmlopParser(target)
|
1041
|
+
elif ExpatParser:
|
1042
|
+
parser = ExpatParser(target)
|
1043
|
+
else:
|
1044
|
+
parser = SlowParser(target)
|
1045
|
+
return parser, target
|
1046
|
+
|
1047
|
+
##
|
1048
|
+
# Convert a Python tuple or a Fault instance to an XML-RPC packet.
|
1049
|
+
#
|
1050
|
+
# @def dumps(params, **options)
|
1051
|
+
# @param params A tuple or Fault instance.
|
1052
|
+
# @keyparam methodname If given, create a methodCall request for
|
1053
|
+
# this method name.
|
1054
|
+
# @keyparam methodresponse If given, create a methodResponse packet.
|
1055
|
+
# If used with a tuple, the tuple must be a singleton (that is,
|
1056
|
+
# it must contain exactly one element).
|
1057
|
+
# @keyparam encoding The packet encoding.
|
1058
|
+
# @return A string containing marshalled data.
|
1059
|
+
|
1060
|
+
def dumps(params, methodname=None, methodresponse=None, encoding=None,
|
1061
|
+
allow_none=0):
|
1062
|
+
"""data [,options] -> marshalled data
|
1063
|
+
|
1064
|
+
Convert an argument tuple or a Fault instance to an XML-RPC
|
1065
|
+
request (or response, if the methodresponse option is used).
|
1066
|
+
|
1067
|
+
In addition to the data object, the following options can be given
|
1068
|
+
as keyword arguments:
|
1069
|
+
|
1070
|
+
methodname: the method name for a methodCall packet
|
1071
|
+
|
1072
|
+
methodresponse: true to create a methodResponse packet.
|
1073
|
+
If this option is used with a tuple, the tuple must be
|
1074
|
+
a singleton (i.e. it can contain only one element).
|
1075
|
+
|
1076
|
+
encoding: the packet encoding (default is UTF-8)
|
1077
|
+
|
1078
|
+
All 8-bit strings in the data structure are assumed to use the
|
1079
|
+
packet encoding. Unicode strings are automatically converted,
|
1080
|
+
where necessary.
|
1081
|
+
"""
|
1082
|
+
|
1083
|
+
assert isinstance(params, TupleType) or isinstance(params, Fault),\
|
1084
|
+
"argument must be tuple or Fault instance"
|
1085
|
+
|
1086
|
+
if isinstance(params, Fault):
|
1087
|
+
methodresponse = 1
|
1088
|
+
elif methodresponse and isinstance(params, TupleType):
|
1089
|
+
assert len(params) == 1, "response tuple must be a singleton"
|
1090
|
+
|
1091
|
+
if not encoding:
|
1092
|
+
encoding = "utf-8"
|
1093
|
+
|
1094
|
+
if FastMarshaller:
|
1095
|
+
m = FastMarshaller(encoding)
|
1096
|
+
else:
|
1097
|
+
m = Marshaller(encoding, allow_none)
|
1098
|
+
|
1099
|
+
data = m.dumps(params)
|
1100
|
+
|
1101
|
+
if encoding != "utf-8":
|
1102
|
+
xmlheader = "<?xml version='1.0' encoding='%s'?>\n" % str(encoding)
|
1103
|
+
else:
|
1104
|
+
xmlheader = "<?xml version='1.0'?>\n" # utf-8 is default
|
1105
|
+
|
1106
|
+
# standard XML-RPC wrappings
|
1107
|
+
if methodname:
|
1108
|
+
# a method call
|
1109
|
+
if not isinstance(methodname, StringType):
|
1110
|
+
methodname = methodname.encode(encoding)
|
1111
|
+
data = (
|
1112
|
+
xmlheader,
|
1113
|
+
"<methodCall>\n"
|
1114
|
+
"<methodName>", methodname, "</methodName>\n",
|
1115
|
+
data,
|
1116
|
+
"</methodCall>\n"
|
1117
|
+
)
|
1118
|
+
elif methodresponse:
|
1119
|
+
# a method response, or a fault structure
|
1120
|
+
data = (
|
1121
|
+
xmlheader,
|
1122
|
+
"<methodResponse>\n",
|
1123
|
+
data,
|
1124
|
+
"</methodResponse>\n"
|
1125
|
+
)
|
1126
|
+
else:
|
1127
|
+
return data # return as is
|
1128
|
+
return string.join(data, "")
|
1129
|
+
|
1130
|
+
##
|
1131
|
+
# Convert an XML-RPC packet to a Python object. If the XML-RPC packet
|
1132
|
+
# represents a fault condition, this function raises a Fault exception.
|
1133
|
+
#
|
1134
|
+
# @param data An XML-RPC packet, given as an 8-bit string.
|
1135
|
+
# @return A tuple containing the unpacked data, and the method name
|
1136
|
+
# (None if not present).
|
1137
|
+
# @see Fault
|
1138
|
+
|
1139
|
+
def loads(data, use_datetime=0):
|
1140
|
+
"""data -> unmarshalled data, method name
|
1141
|
+
|
1142
|
+
Convert an XML-RPC packet to unmarshalled data plus a method
|
1143
|
+
name (None if not present).
|
1144
|
+
|
1145
|
+
If the XML-RPC packet represents a fault condition, this function
|
1146
|
+
raises a Fault exception.
|
1147
|
+
"""
|
1148
|
+
p, u = getparser(use_datetime=use_datetime)
|
1149
|
+
p.feed(data)
|
1150
|
+
p.close()
|
1151
|
+
return u.close(), u.getmethodname()
|
1152
|
+
|
1153
|
+
|
1154
|
+
# --------------------------------------------------------------------
|
1155
|
+
# request dispatcher
|
1156
|
+
|
1157
|
+
class _Method:
|
1158
|
+
# some magic to bind an XML-RPC method to an RPC server.
|
1159
|
+
# supports "nested" methods (e.g. examples.getStateName)
|
1160
|
+
def __init__(self, send, name):
|
1161
|
+
self.__send = send
|
1162
|
+
self.__name = name
|
1163
|
+
def __getattr__(self, name):
|
1164
|
+
return _Method(self.__send, "%s.%s" % (self.__name, name))
|
1165
|
+
def __call__(self, *args):
|
1166
|
+
return self.__send(self.__name, args)
|
1167
|
+
|
1168
|
+
##
|
1169
|
+
# Standard transport class for XML-RPC over HTTP.
|
1170
|
+
# <p>
|
1171
|
+
# You can create custom transports by subclassing this method, and
|
1172
|
+
# overriding selected methods.
|
1173
|
+
|
1174
|
+
class Transport:
|
1175
|
+
"""Handles an HTTP transaction to an XML-RPC server."""
|
1176
|
+
|
1177
|
+
# client identifier (may be overridden)
|
1178
|
+
user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__
|
1179
|
+
|
1180
|
+
def __init__(self, use_datetime=0):
|
1181
|
+
self._use_datetime = use_datetime
|
1182
|
+
|
1183
|
+
##
|
1184
|
+
# Send a complete request, and parse the response.
|
1185
|
+
#
|
1186
|
+
# @param host Target host.
|
1187
|
+
# @param handler Target PRC handler.
|
1188
|
+
# @param request_body XML-RPC request body.
|
1189
|
+
# @param verbose Debugging flag.
|
1190
|
+
# @return Parsed response.
|
1191
|
+
|
1192
|
+
def request(self, host, handler, request_body, verbose=0):
|
1193
|
+
# issue XML-RPC request
|
1194
|
+
|
1195
|
+
h = self.make_connection(host)
|
1196
|
+
if verbose:
|
1197
|
+
h.set_debuglevel(1)
|
1198
|
+
|
1199
|
+
self.send_request(h, handler, request_body)
|
1200
|
+
self.send_host(h, host)
|
1201
|
+
self.send_user_agent(h)
|
1202
|
+
self.send_content(h, request_body)
|
1203
|
+
|
1204
|
+
errcode, errmsg, headers = h.getreply()
|
1205
|
+
|
1206
|
+
if errcode != 200:
|
1207
|
+
raise ProtocolError(
|
1208
|
+
host + handler,
|
1209
|
+
errcode, errmsg,
|
1210
|
+
headers
|
1211
|
+
)
|
1212
|
+
|
1213
|
+
self.verbose = verbose
|
1214
|
+
|
1215
|
+
try:
|
1216
|
+
sock = h._conn.sock
|
1217
|
+
except AttributeError:
|
1218
|
+
sock = None
|
1219
|
+
|
1220
|
+
return self._parse_response(h.getfile(), sock)
|
1221
|
+
|
1222
|
+
##
|
1223
|
+
# Create parser.
|
1224
|
+
#
|
1225
|
+
# @return A 2-tuple containing a parser and a unmarshaller.
|
1226
|
+
|
1227
|
+
def getparser(self):
|
1228
|
+
# get parser and unmarshaller
|
1229
|
+
return getparser(use_datetime=self._use_datetime)
|
1230
|
+
|
1231
|
+
##
|
1232
|
+
# Get authorization info from host parameter
|
1233
|
+
# Host may be a string, or a (host, x509-dict) tuple; if a string,
|
1234
|
+
# it is checked for a "user:pw@host" format, and a "Basic
|
1235
|
+
# Authentication" header is added if appropriate.
|
1236
|
+
#
|
1237
|
+
# @param host Host descriptor (URL or (URL, x509 info) tuple).
|
1238
|
+
# @return A 3-tuple containing (actual host, extra headers,
|
1239
|
+
# x509 info). The header and x509 fields may be None.
|
1240
|
+
|
1241
|
+
def get_host_info(self, host):
|
1242
|
+
|
1243
|
+
x509 = {}
|
1244
|
+
if isinstance(host, TupleType):
|
1245
|
+
host, x509 = host
|
1246
|
+
|
1247
|
+
import urllib
|
1248
|
+
auth, host = urllib.splituser(host)
|
1249
|
+
|
1250
|
+
if auth:
|
1251
|
+
import base64
|
1252
|
+
auth = base64.encodestring(urllib.unquote(auth))
|
1253
|
+
auth = string.join(string.split(auth), "") # get rid of whitespace
|
1254
|
+
extra_headers = [
|
1255
|
+
("Authorization", "Basic " + auth)
|
1256
|
+
]
|
1257
|
+
else:
|
1258
|
+
extra_headers = None
|
1259
|
+
|
1260
|
+
return host, extra_headers, x509
|
1261
|
+
|
1262
|
+
##
|
1263
|
+
# Connect to server.
|
1264
|
+
#
|
1265
|
+
# @param host Target host.
|
1266
|
+
# @return A connection handle.
|
1267
|
+
|
1268
|
+
def make_connection(self, host):
|
1269
|
+
# create a HTTP connection object from a host descriptor
|
1270
|
+
import httplib
|
1271
|
+
host, extra_headers, x509 = self.get_host_info(host)
|
1272
|
+
return httplib.HTTP(host)
|
1273
|
+
|
1274
|
+
##
|
1275
|
+
# Send request header.
|
1276
|
+
#
|
1277
|
+
# @param connection Connection handle.
|
1278
|
+
# @param handler Target RPC handler.
|
1279
|
+
# @param request_body XML-RPC body.
|
1280
|
+
|
1281
|
+
def send_request(self, connection, handler, request_body):
|
1282
|
+
connection.putrequest("POST", handler)
|
1283
|
+
|
1284
|
+
##
|
1285
|
+
# Send host name.
|
1286
|
+
#
|
1287
|
+
# @param connection Connection handle.
|
1288
|
+
# @param host Host name.
|
1289
|
+
|
1290
|
+
def send_host(self, connection, host):
|
1291
|
+
host, extra_headers, x509 = self.get_host_info(host)
|
1292
|
+
connection.putheader("Host", host)
|
1293
|
+
if extra_headers:
|
1294
|
+
if isinstance(extra_headers, DictType):
|
1295
|
+
extra_headers = extra_headers.items()
|
1296
|
+
for key, value in extra_headers:
|
1297
|
+
connection.putheader(key, value)
|
1298
|
+
|
1299
|
+
##
|
1300
|
+
# Send user-agent identifier.
|
1301
|
+
#
|
1302
|
+
# @param connection Connection handle.
|
1303
|
+
|
1304
|
+
def send_user_agent(self, connection):
|
1305
|
+
connection.putheader("User-Agent", self.user_agent)
|
1306
|
+
|
1307
|
+
##
|
1308
|
+
# Send request body.
|
1309
|
+
#
|
1310
|
+
# @param connection Connection handle.
|
1311
|
+
# @param request_body XML-RPC request body.
|
1312
|
+
|
1313
|
+
def send_content(self, connection, request_body):
|
1314
|
+
connection.putheader("Content-Type", "text/xml")
|
1315
|
+
connection.putheader("Content-Length", str(len(request_body)))
|
1316
|
+
connection.endheaders()
|
1317
|
+
if request_body:
|
1318
|
+
connection.send(request_body)
|
1319
|
+
|
1320
|
+
##
|
1321
|
+
# Parse response.
|
1322
|
+
#
|
1323
|
+
# @param file Stream.
|
1324
|
+
# @return Response tuple and target method.
|
1325
|
+
|
1326
|
+
def parse_response(self, file):
|
1327
|
+
# compatibility interface
|
1328
|
+
return self._parse_response(file, None)
|
1329
|
+
|
1330
|
+
##
|
1331
|
+
# Parse response (alternate interface). This is similar to the
|
1332
|
+
# parse_response method, but also provides direct access to the
|
1333
|
+
# underlying socket object (where available).
|
1334
|
+
#
|
1335
|
+
# @param file Stream.
|
1336
|
+
# @param sock Socket handle (or None, if the socket object
|
1337
|
+
# could not be accessed).
|
1338
|
+
# @return Response tuple and target method.
|
1339
|
+
|
1340
|
+
def _parse_response(self, file, sock):
|
1341
|
+
# read response from input file/socket, and parse it
|
1342
|
+
|
1343
|
+
p, u = self.getparser()
|
1344
|
+
|
1345
|
+
while 1:
|
1346
|
+
if sock:
|
1347
|
+
response = sock.recv(1024)
|
1348
|
+
else:
|
1349
|
+
response = file.read(1024)
|
1350
|
+
if not response:
|
1351
|
+
break
|
1352
|
+
if self.verbose:
|
1353
|
+
print "body:", repr(response)
|
1354
|
+
p.feed(response)
|
1355
|
+
|
1356
|
+
file.close()
|
1357
|
+
p.close()
|
1358
|
+
|
1359
|
+
return u.close()
|
1360
|
+
|
1361
|
+
##
|
1362
|
+
# Standard transport class for XML-RPC over HTTPS.
|
1363
|
+
|
1364
|
+
class SafeTransport(Transport):
|
1365
|
+
"""Handles an HTTPS transaction to an XML-RPC server."""
|
1366
|
+
|
1367
|
+
# FIXME: mostly untested
|
1368
|
+
|
1369
|
+
def make_connection(self, host):
|
1370
|
+
# create a HTTPS connection object from a host descriptor
|
1371
|
+
# host may be a string, or a (host, x509-dict) tuple
|
1372
|
+
import httplib
|
1373
|
+
host, extra_headers, x509 = self.get_host_info(host)
|
1374
|
+
try:
|
1375
|
+
HTTPS = httplib.HTTPS
|
1376
|
+
except AttributeError:
|
1377
|
+
raise NotImplementedError(
|
1378
|
+
"your version of httplib doesn't support HTTPS"
|
1379
|
+
)
|
1380
|
+
else:
|
1381
|
+
return HTTPS(host, None, **(x509 or {}))
|
1382
|
+
|
1383
|
+
##
|
1384
|
+
# Standard server proxy. This class establishes a virtual connection
|
1385
|
+
# to an XML-RPC server.
|
1386
|
+
# <p>
|
1387
|
+
# This class is available as ServerProxy and Server. New code should
|
1388
|
+
# use ServerProxy, to avoid confusion.
|
1389
|
+
#
|
1390
|
+
# @def ServerProxy(uri, **options)
|
1391
|
+
# @param uri The connection point on the server.
|
1392
|
+
# @keyparam transport A transport factory, compatible with the
|
1393
|
+
# standard transport class.
|
1394
|
+
# @keyparam encoding The default encoding used for 8-bit strings
|
1395
|
+
# (default is UTF-8).
|
1396
|
+
# @keyparam verbose Use a true value to enable debugging output.
|
1397
|
+
# (printed to standard output).
|
1398
|
+
# @see Transport
|
1399
|
+
|
1400
|
+
class ServerProxy:
|
1401
|
+
"""uri [,options] -> a logical connection to an XML-RPC server
|
1402
|
+
|
1403
|
+
uri is the connection point on the server, given as
|
1404
|
+
scheme://host/target.
|
1405
|
+
|
1406
|
+
The standard implementation always supports the "http" scheme. If
|
1407
|
+
SSL socket support is available (Python 2.0), it also supports
|
1408
|
+
"https".
|
1409
|
+
|
1410
|
+
If the target part and the slash preceding it are both omitted,
|
1411
|
+
"/RPC2" is assumed.
|
1412
|
+
|
1413
|
+
The following options can be given as keyword arguments:
|
1414
|
+
|
1415
|
+
transport: a transport factory
|
1416
|
+
encoding: the request encoding (default is UTF-8)
|
1417
|
+
|
1418
|
+
All 8-bit strings passed to the server proxy are assumed to use
|
1419
|
+
the given encoding.
|
1420
|
+
"""
|
1421
|
+
|
1422
|
+
def __init__(self, uri, transport=None, encoding=None, verbose=0,
|
1423
|
+
allow_none=0, use_datetime=0):
|
1424
|
+
# establish a "logical" server connection
|
1425
|
+
|
1426
|
+
# get the url
|
1427
|
+
import urllib
|
1428
|
+
type, uri = urllib.splittype(uri)
|
1429
|
+
if type not in ("http", "https"):
|
1430
|
+
raise IOError, "unsupported XML-RPC protocol"
|
1431
|
+
self.__host, self.__handler = urllib.splithost(uri)
|
1432
|
+
if not self.__handler:
|
1433
|
+
self.__handler = "/RPC2"
|
1434
|
+
|
1435
|
+
if transport is None:
|
1436
|
+
if type == "https":
|
1437
|
+
transport = SafeTransport(use_datetime=use_datetime)
|
1438
|
+
else:
|
1439
|
+
transport = Transport(use_datetime=use_datetime)
|
1440
|
+
self.__transport = transport
|
1441
|
+
|
1442
|
+
self.__encoding = encoding
|
1443
|
+
self.__verbose = verbose
|
1444
|
+
self.__allow_none = allow_none
|
1445
|
+
|
1446
|
+
def __request(self, methodname, params):
|
1447
|
+
# call a method on the remote server
|
1448
|
+
|
1449
|
+
request = dumps(params, methodname, encoding=self.__encoding,
|
1450
|
+
allow_none=self.__allow_none)
|
1451
|
+
|
1452
|
+
response = self.__transport.request(
|
1453
|
+
self.__host,
|
1454
|
+
self.__handler,
|
1455
|
+
request,
|
1456
|
+
verbose=self.__verbose
|
1457
|
+
)
|
1458
|
+
|
1459
|
+
if len(response) == 1:
|
1460
|
+
response = response[0]
|
1461
|
+
|
1462
|
+
return response
|
1463
|
+
|
1464
|
+
def __repr__(self):
|
1465
|
+
return (
|
1466
|
+
"<ServerProxy for %s%s>" %
|
1467
|
+
(self.__host, self.__handler)
|
1468
|
+
)
|
1469
|
+
|
1470
|
+
__str__ = __repr__
|
1471
|
+
|
1472
|
+
def __getattr__(self, name):
|
1473
|
+
# magic method dispatcher
|
1474
|
+
return _Method(self.__request, name)
|
1475
|
+
|
1476
|
+
# note: to call a remote object with an non-standard name, use
|
1477
|
+
# result getattr(server, "strange-python-name")(args)
|
1478
|
+
|
1479
|
+
# compatibility
|
1480
|
+
|
1481
|
+
Server = ServerProxy
|
1482
|
+
|
1483
|
+
# --------------------------------------------------------------------
|
1484
|
+
# test code
|
1485
|
+
|
1486
|
+
if __name__ == "__main__":
|
1487
|
+
|
1488
|
+
# simple test program (from the XML-RPC specification)
|
1489
|
+
|
1490
|
+
# server = ServerProxy("http://localhost:8000") # local server
|
1491
|
+
server = ServerProxy("http://time.xmlrpc.com/RPC2")
|
1492
|
+
|
1493
|
+
print server
|
1494
|
+
|
1495
|
+
try:
|
1496
|
+
print server.currentTime.getCurrentTime()
|
1497
|
+
except Error, v:
|
1498
|
+
print "ERROR", v
|
1499
|
+
|
1500
|
+
multi = MultiCall(server)
|
1501
|
+
multi.currentTime.getCurrentTime()
|
1502
|
+
multi.currentTime.getCurrentTime()
|
1503
|
+
try:
|
1504
|
+
for response in multi():
|
1505
|
+
print response
|
1506
|
+
except Error, v:
|
1507
|
+
print "ERROR", v
|
1508
|
+
</code></pre>
|
1509
|
+
</body>
|
1510
|
+
</html>
|