_Jc@sNdZddkZddkZddkZddkZddkZddkZddkZddkZddkl Z l Z l Z ddk lZddklZddklZlZddkZddklZlZlZlZddklZdd klZlZdd k l!Z!dd k"l#Z#dd k$l%Z%dd k&l'Z'ei(e)Z*dZ+dZ,defdYZ-de-fdYZ.dZ/dZ0dZ1dZ2dZ3dZ4de-fdYZ5de.fdYZ6de6fdYZ7d Z d!Z8d"Z9d#Z:dddd$d%dgZ;dS(&s< Controller Classes, dispatch methods and helper functions for controller operation. This module contains the main classes which describe Turbogears2 Controllers. These Controllers are handled by the Dispatch functions which are also provided here. Lastly, url definition and browser redirection are defined here. iN(turltconfigtrequest(tWSGIController(tabort(tNotAuthorizedErrort not_anonymous(t HTTPFoundt HTTPNotFoundt HTTPExceptiontHTTPClientError(trender(texposet allow_only(t setup_i18n(tflash(tRequest(tHTTPUnauthorizeds CUSTOM/LEAVEcCs6tii}t|dpt|_n|iS(s Returns a set containing the names of the currently configured template engines from the active application's globals ttg_configured_engines(tpylonst app_globalst _current_objthasattrtsetR(tg((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt_configured_engines*stDecoratedControllercBsbeZdZdZdZdZdZd dZdZ dZ dZ d Z RS( s& DecoratedController takes action on the decorated controller methods created by the decorators in tg.decorators. The decorators in tg.decorators create an attribute named 'decoration' on the controller method, creating rules as to: 1) how to validate the request, 2) how to render the response, 3) allowing hooks to be registered to happen: a) before validation b) before the controller method is called c) before the rendering takes place, and d) after the rendering has happened. cOs\t|do/|idj o|i}t||}ntt|i||dS(NR (RR tNonetsuperRt__init__(tselftargstkwargst predicate((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRGs  cOsdS(s Override this method to define any action you would like taken before the controller code is executed. This is particularly useful for defining a Controller-wide specification (all methods) for things like: setting up variables/objects in the template context, restricting access, or other tasks which should be executed before the controller method is called. N((RRtkw((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt __before__OscOsdS(sOverride this method to define what you would like to run after the template has been rendered. This method will always be run after your method, even if it raises an Exception or redirects. An example use-case would be a runtime-specific template change, you where would want to change the template back to the originally decorated template after you have temporarily changed it. N((RRR"((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt __after__YscCs{y|ii}Wn#tj oh|i_}nXy||i}Wn-tj o!ti|}||i      c Cs@|iit\}}}}|tjo|tiidtstriptvalueRAR9RUt error_handlerRRBRR( RRHRJRIt exceptiont error_listterrort field_valueRRQ((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRFjs&  "  cCshti_hti_dS(N(RR@RRA(R((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR6s N( t__name__t __module__t__doc__RR#R$R/RRTR?RGRFR6(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR5s  M X W +tObjectDispatchControllercBs2eZdZddZdZdddZRS(s Object dispatch (also "object publishing") means that each portion of the URL becomes a lookup on an object. The next part of the URL applies to the next object, until you run out of URL. Processing starts on a "Root" object. Thus, /foo/bar/baz become URL portion "foo", "bar", and "baz". The dispatch looks for the "foo" attribute on the Root URL, which returns another object. The "bar" attribute is looked for on the new object, which returns another object. The "baz" attribute is similarly looked for on this object. Dispatch does not have to be directly on attribute lookup, objects can also have other methods to explain how to dispatch from them. The search ends when a decorated controller method is found. The rules work as follows: 1) If the current object under consideration is a decorated controller method, the search is ended. 2) If the current object under consideration has a "default" method, keep a record of that method. If we fail in our search, and the most recent method recorded is a "default" method, then the search is ended with that method returned. 3) If the current object under consideration has a "lookup" method, keep a record of that method. If we fail in our search, and the most recent method recorded is a "lookup" method, then execute the "lookup" method, and start the search again on the return value of that method. 4) If the URL portion exists as an attribute on the object in question, start searching again on that attribute. 5) If we fail our search, try the most recent recorded methods as per 2 and 3. cCs|djotiidd}n|id}t||\}}|o$di|t| ti_ n |ti_ |o|ddjo|i n||ti i fS(s Returns a tuple (controller, remainder, params) :Parameters: url url as string t/iitN( RRtpathRt_object_dispatchtjoinR>RR@tcontroller_urlRRItmixed(RRturl_pathRHRJ((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt_get_routing_infos $ cCs|i|id\}}}|i}|djp |djog|djo$t|ido|ii|S|djo$t|ido|ii|SdSti |||d|S(NRR#R$RJ( RR;RRtim_classRR#R$RRT(RR,RRHRJRIt func_name((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRTs!   RcKsdS(s This function does not do anything. It is a placeholder that allows Routes to accept this controller as a target for its routing. N((RRR7R ((s2/usr/lib/python2.6/site-packages/tg/controllers.pytroutes_placeholdersN(RRRRRRTR(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs%  cCsEt|do |i}n|}t|do|indS(sthis function checks if a controller has a 'alow_only' attribute and if it is the case, test that this require predicate can be evaled to True. It will raise a Forbidden exception if the predicate is not valid. Rt_check_securityN(RRR(tobjtklass_instance((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt_check_controller_auths  c Cs|}dt_dt_|oxd|djog|d}ti|\}}|o=|id}||}|| |d<|t_|t_qng}xtoy/t|||\}} }t || |SWqt j o} t i d|qt j o} | idjo | in|p | in|i\} }} }| djot || |S||\}}t|qqXqWdS(Nt.isa 401 error occured for obj: %sitdefault(RRt response_typet response_extt mimetypest guess_typetrfindR~t _find_objectt_find_restful_dispatchRtlogtdebugR t status_intRRtlist( RRRJtlast_remaindert mime_typetencodingtextension_spott extensiontnotfound_handlerstparentthttpeteRP((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs@         c Cst|ti| ot|t o ||fStii}}ti}d|jo#|do|di}qn|o|ddjo|d }n|oet |}|djo|ddjo{|djo|d}n|djo!t |djo|d }n|djo!t |djo|d }qnL|djo6|dd jo%d }|djo|d }qn |djo|d jp |d jot |d ot |d }t ti |d d}||} t | d jo<t || d o(t tt || d | dgSt ||d o(t tt ||d |dgStin|ojt ||d oV|d djoEti|o |}nt tt ||d |dgSn| oJ|djo=t |do-t |ido|iiio d}nt |d jo#|djot |d ot |ido|iiiot |djo d }qt |d }t ti |d d}||}t |d jo<t ||d o(t tt ||d |dgSt |d o!ti |ido d }qtin|djoJ|d jo=t |do-t |ido|iiio d}n|d joJ|d jo=t |do-t |ido|iiio d}nt ||out ||} t | doF| iio9ti|o |}n||_t ||}qtin!t|totin||fS(Nt_methodiRitnewteditR;itdeletetposttputtget_oneitget_allR9t get_deletet post_delete(snewR(snewR(RR*tisclassR_tRestControllerRtmethodtlowerRIR>RR[R+RRRRRR9texposedRRRR( RRRJtrequest_methodRRIt remainder_lenR,targ_lent new_remaindertpossible_rest_method((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR&s "         7 '((, ,H S  '(' M M   cCsd}xto|djotint|t|o|||fS| p$t|djob|ddjoQt|tot |}nt |dd}t|o|||fSnt |\}}|o|i d|||fn|oI|oBt|djo|ddj o|i d|||fn|ptin|}y-t ||di dd}|d}Wq tj otiq Xq WdS(NiiRtindexRtlookupsutf-8(RR~RRRt _iscontrollerR>R_ttupleRR[t_get_notfound_handlerstappendtencodetUnicodeEncodeError(RRJRRRRR((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs6   , 3cCs+d}}xt|D]}t||}t|do_t|idpddk}|in|iio |}q|iio |}qqqW|djo4t|dd}|ot |o |}qn|djo4t|dd}|ot |o |}q!n||fS(s9Return (default,lookup) notfound handlers for this objectR9tis_default_controlleriNRR( RtdirR[RR9tpdbt set_traceRtis_lookup_controllerR(RRRRPtmethR((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs*        cCs4t|dptSt|dptS|iiS(Nt__call__R9(RRgR9R(R((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs RcBs3eZdZdefdYZedZRS(sA Decorated Controller that dispatches in a RESTful Manner. This controller was designed to follow Representational State Transfer protocol, also known as REST. The goal of this controller method is to provide the developer a way to map RESTful URLS to controller methods directly, while still allowing Normal Object Dispatch to occur. Here is a brief rundown of the methods which are called on dispatch along with an example URL. +-----------------+--------------------------------------------------------------+--------------------------------------------+ | Method | Description | Example Method(s) / URL(s) | +=================+==============================================================+============================================+ | get_one | Display one record. | GET /movies/1 | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | get_all | Display all records in a resource. | GET /movies/ | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | get | A combo of get_one and get_all. | GET /movies/ | | | +--------------------------------------------+ | | | GET /movies/1 | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | new | Display a page to prompt the User for resource creation. | GET /movies/new | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | edit | Display a page to prompt the User for resource modification. | GET /movies/1/edit | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | post | Create a new record. | POST /movies/ | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | put | Update an existing record. | POST /movies/1?_method=PUT | | | +--------------------------------------------+ | | | PUT /movies/1 | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | post_delete | Delete an existing record. | POST /movies/1?_method=DELETE | | | +--------------------------------------------+ | | | DELETE /movies/1 | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | get_delete | Display a delete Confirmation page. | GET /movies/1/delete | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | delete | A combination of post_delete and get_delete. | GET /movies/delete | | | +--------------------------------------------+ | | | DELETE /movies/1 | | | +--------------------------------------------+ | | | DELETE /movies/ | | | +--------------------------------------------+ | | | POST /movies/1/delete | | | +--------------------------------------------+ | | | POST /movies/delete | +-----------------+--------------------------------------------------------------+--------------------------------------------+ You may note the ?_method on some of the URLs. This is basically a hack because exiting browsers do not support the PUT and DELETE methods. Just note that if you decide to use a this resource with a web browser, you will likely have to add a _method as a hidden field in your forms for these items. Also note that RestController differs from TGController in that it offers no index, default, or lookup. It is intended primarily for resource management. :References: `Controller <../main/Controllers.html>`_ A basic overview on how to write controller methods. `CrudRestController <../main/Extensions/Crud/index.html>`_ A way to integrate ToscaWdiget Functionality with RESTful Dispatch. R9cBseZdZeZdZZRS(s^This is here so that the Object Dispatcher will recognize this class as an exposed controller.N(RRRR~RRRR(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR9scCst|d p|idjotidtitSy|i}|iti Wnt j o}t |}t|do|i |nt iti od}d}n d}d}|ti_t|d|t|d |nXdS( NR s&No controller-wide authorization at %st_failed_authorizationiRitwarningtstatustcomment(RR RRRRRR~tcheck_authorizationRRtunicodeRRtis_metRRSRRR(tclsR!RtreasontcodeR((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs$!    (RRRtobjectR9t classmethodR(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs:t TGControllercBs eZdZdZdZRS(s TGController is a specialized form of ObjectDispatchController that forms the basis of standard TurboGears controllers. The "Root" controller of a standard tg project must be a TGController. This controller can be used as a baseclass for anything in the object dispatch tree, but it MUST be used in the Root controller and any controller which you intend to do object dispatch from using Routes. This controller has a few reserved method names which provide special functionality. +-----------------+--------------------------------------------------------------+--------------------------------------------+ | Method | Description | Example URL(s) | +=================+==============================================================+============================================+ | index | The root of the controller. | / | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | default | A method to call when all other methods have failed. | /movies | +-----------------+--------------------------------------------------------------+--------------------------------------------+ | lookup | Allows the developer to return a | /location/23.35/2343.34/elevation | | | Controller instance for further dispatch. | | +-----------------+--------------------------------------------------------------+--------------------------------------------+ :References: `Controller <../main/Controllers.html>`_ A basic overview on how to write controller methods. c Cs\td}t|tod|jo|d}ny|i|\}}}|i}|p g}n|djp |djog|djo$t|ido|ii |S|djo$t|ido|ii |SdSt i |||d|}WnKt j o?} | }|idjo|iiddnt|_nX|S(NRR#R$RJi0s Content-Type(RRR_RBRRRRRR#R$RRTR RR8RR~t _exception( RR,Rt routingArgsRHRJRIRRR((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRTCs.    cCst|d p|idjotidtitSy|i}|iti Wnt j o}t |}t|do|i |nt iti od}d}n d}d}|ti_t|d|t|d |nXdS( NR s&No controller-wide authorization at %sRiRiRRR(RR RRRRRR~RRRRRRRRRSRRR(RR!RRRR((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRcs$!    (RRRRTR(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR$s tWSGIAppControllercBs5eZdZddZedZdZRS(s7 A controller you can use to mount a WSGI app. cCs3||_||_ttdt path_infoRRtxranget path_info_poptredirectt body_filetseektdelegateRR7(RRR"Rtnew_reqtto_popRN((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs  +  cCs|i||S(s Delegates the request to the WSGI app. Override me if you need to update the environ, mangle response, etc... (R(RRR7((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRsN(RRRRRR RR(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR}s cOsCt|}t|dtodi|d|dRRRt pylons_url(RR RI((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs$   'cOs2t||tdt||i}|dS(sGenerate an HTTP redirect. The function raises an exception internally, which is handled by the framework. The URL may be either absolute (e.g. http://example.com or /myfile.html) or relative. Relative URLs are automatically converted to absolute URLs. Parameters may be specified, which are appended to the URL. This causes an external redirect via the browser; if the request is POST, the browser will issue GET for the second request. tlocationN(RRR(RR tfound((s2/usr/lib/python2.6/site-packages/tg/controllers.pyRs cCs|titiS(N(RRR7(twsgi_app((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt use_wsgi_appscCsddkl}ddkl}||}||joXytii}Wntj o}|}nX|p |}n|i|}n|S(Ni(tugettext(tNullTranslations(t pylons.i18nR tgettextR RR@tformencode_translationR'(Rtpylons_gettextR ttranstfetranst attrerror((s2/usr/lib/python2.6/site-packages/tg/controllers.pyR^s   RR(<RtloggingtwarningsturlparseturllibRR*RCRRRRRtpylons.controllersRtpylons.controllers.utilRtrepoze.what.predicatesRRRt tg.exceptionsRRR R t tg.renderR Rt tg.decoratorsR R ttg.i18nRttg.flashRtwebobRt webob.excRt getLoggerRRR}RRRRRRRRRRRRRR R^t__all__(((s2/usr/lib/python2.6/site-packages/tg/controllers.pyt sP       " eS - Y +  \Y* &