;ò X¥ÄFc@sdklZlZdZdkZdkZdkZdkZdkZdk Zdk Z ydk l Z Wn e j odk l Z nXdkZdkZdklZdZedZeeidƒƒZdfd „ƒYZd fd „ƒYZd „Zd efd„ƒYZdefd„ƒYZdefd„ƒYZd„Zd„Z d„Z!d„Z"dZ#d„Z$d„Z%dS((s nested_scopess generatorss$Revision: 1099 $N(sStringIO(s FileEntrys1.4.2s 8/16/2007s.s PyBlosxomcBsttZdZed„Zd„Zd„Zd„Zd„Ze d„Z dd„Z d „Z d d „Z d „ZRS( sâ This is the main class for PyBlosxom functionality. It handles initialization, defines default behavior, and also pushes the request through all the steps until the output is rendered and we're complete. cCs6d|d…ss defaultfunccCs|S(N(sx(sx((s./Pyblosxom/pyblosxom.pys†ss extensionsN(sselfs_requestsgetDatasdatasgetHttpspyhttpsgetConfigurationsconfigsgetslocales setlocalesLC_ALLsErrorstoolss initializes VERSION_DATEshas_keysendswithsdatadirs plugin_utilssinitialize_pluginssNones run_callbacksblosxom_entry_parser(sselfsdataspyhttpsdatadirsconfig((s./Pyblosxom/pyblosxom.pys initializePs8    +      cCsNtiƒ}|iƒ}|id|iƒ|id|iƒti ƒdS(sæ This cleans up PyBlosxom after a run. Mostly it calls tools.cleanup which in turn shuts down the logging. This should be called when Pyblosxom has done all its work right before exiting. s status = %ss headers = %sN( stoolss getLoggerslogsselfs getResponsesresponsesdebugsstatussheadersscleanup(sselfslogsresponse((s./Pyblosxom/pyblosxom.pyscleanupˆs   cCs |iSdS(s– Returns the L{Request} object for this PyBlosxom instance. @returns: the request object @rtype: L{Request} N(sselfs_request(sself((s./Pyblosxom/pyblosxom.pys getRequest™scCs|iiƒSdS(së Returns the L{Response} object which handles all output related functionality for this PyBlosxom instance. @see: L{Response} @returns: the reponse object @rtype: L{Response} N(sselfs_requests getResponse(sself((s./Pyblosxom/pyblosxom.pys getResponse¢s cCsÑ|iƒ|tjo|iƒiƒntidhd|i<ƒtidhd|iÇssdonefunccCs|S(N(sx(sx((s./Pyblosxom/pyblosxom.pysÈsisendN( sselfs initializesstaticsFalses getRequestsbuffer_input_streamstoolss run_callbacks_requestshandledsblosxom_handlerscleanup(sselfsstaticshandled((s./Pyblosxom/pyblosxom.pysrun®s      shelpcCsz|iƒtidhd|i<ƒti|hd|iêssdonefunccCs|S(N(sx(sx((s./Pyblosxom/pyblosxom.pysëssendN(sselfs initializestoolss run_callbacks_requestscallbackshandled(sselfscallbackshandled((s./Pyblosxom/pyblosxom.pys runCallbackÕs    cCsÕ|iƒ|iiƒ}|iiƒ}|idƒdjo.||idƒ }||idƒd}nd}|i t i dƒ}t i|||ƒ}|itiƒ|itiƒ|iƒGH|iƒdS(s  Renders a single page from the blog. @param url: the url to render--this has to be relative to PyBlosxom @type url: string @param headers: 1 if you want the headers rendered and 0 if not. @type headers: int s?iÿÿÿÿiss/N(sselfs initializes_requestsgetConfigurationsconfigsgetDatasdatasurlsfindsquerysreplacesosssepstoolss render_urlsresponses sendHeadersssyssstdoutssendBodysreadscleanup(sselfsurlsheaderssdatasquerysconfigsresponse((s./Pyblosxom/pyblosxom.pys runRenderOneòs   ic Csƒ|iƒ|iiƒ}|iiƒ}dGH|o dGHn|iddƒ}|d} | ot dƒ‚n|iddgƒ}g}|id d ƒ} |id d ƒ}h}h} ti|i| ƒ} x8| D]0}||id ƒd }||diƒj oqØntiti|i|ƒƒ}|t| ƒ|id ƒ!}tii ||ƒ}y#ti"|d |d ƒd}Wn d }nX||jp| o\tii$|ƒi%ti&ƒ}xAt(t|ƒd ƒD])}ti&i*|d |!ƒ}d | |} with syntax as:: request.getHttp()['form'] instead of:: request.getForm() cCs'ti|ƒ||_|i|ƒdS(só Wraps an environment (which is a dict) and a request. @param request: the Request object for this request @type request: Request @param env: the environment for this request @type env: dict N(sdicts__init__sselfsrequests_requestsupdatesenv(sselfsrequestsenv((s./Pyblosxom/pyblosxom.pys__init__s   cCs2|djo|iiƒSnti||ƒSdS(s If the key argument is "form", we return the _request.getForm(). Otherwise this returns the item for that key in the wrapped dict. @param key: the key requested @type key: string @returns: varies @rtype: varies sformN(skeysselfs_requestsgetFormsdicts __getitem__(sselfskey((s./Pyblosxom/pyblosxom.pys __getitem__s  (s__name__s __module__s__doc__s__init__s __getitem__(((s./Pyblosxom/pyblosxom.pysEnvDictýs  sRequestcBsžtZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„ZRS(sš This class holds the PyBlosxom request. It holds configuration information, HTTP/CGI information, and data that we calculate and transform over the course of execution. There should be only one instance of this class floating around and it should get created by pyblosxom.cgi and passed into the PyBlosxom instance which will do further manipulation on the Request instance. cCsÁ||_t||ƒ|_|tjotƒ|_ n ||_ t ƒ|_ |i i |_ |i i |_ |i i|_|i i|_|i i|_t|_t|_|it|ƒƒdS(s² Sets configuration and environment. Creates the L{Response} object which handles all output related functionality. @param config: A dict containing the configuration variables. @type config: dict @param environ: A dict containing the environment variables. @type environ: dict @param data: A dict containing data variables. @type data: dict N(sconfigsselfs_configurationsEnvDictsenvirons_httpsdatasNonesdicts_datasStringIOs_insreadsreadlines readlinessseekstells_forms _responses setResponsesResponse(sselfsconfigsenvironsdata((s./Pyblosxom/pyblosxom.pys__init__2s      cCs |iSdS(sê Can't copy the __iter__ method over from the StringIO instance cause iter looks for the method in the class instead of the instance. See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252151 N(sselfs_in(sself((s./Pyblosxom/pyblosxom.pys__iter__escCs§|iƒ}|d}|d}|djovyt|iddƒƒ}Wntj o d}nX|djo-|i i |i |ƒƒ|i i dƒq£ndS(s  Buffer the input stream in a StringIO instance. This is done to have a known/consistent way of accessing incomming data. For example the input stream passed by mod_python does not offer the same functionallity as sys.stdin. s wsgi.inputsREQUEST_METHODsGETsCONTENT_LENGTHiN( sselfsgetHttpspyhttpswinputsmethodsintsgetslengths ValueErrors_inswritesreadsseek(sselfswinputslengthspyhttpsmethod((s./Pyblosxom/pyblosxom.pysbuffer_input_streamns      cCs||_||iƒd} instance is created only when requested to prevent overhead and unnecessary consumption of the input stream. @returns: L{cgi.FieldStorage} @rtype: object N(sselfs_formsNones_Request__getform(sself((s./Pyblosxom/pyblosxom.pysgetForm¬s cCs |iSdS(s. Returns the _actual_ configuration dict. The configuration dict holds values that the user sets in their config.py file. Modifying the contents of the dict will affect all downstream processing. @returns: the configuration dict @rtype: dict N(sselfs_configuration(sself((s./Pyblosxom/pyblosxom.pysgetConfigurationºs cCs |iSdS(s Returns the _actual_ http dict. Holds HTTP/CGI data derived from the environment of execution. Modifying the contents of the dict will affect all downstream processing. @returns: the http environment dict @rtype: dict N(sselfs_http(sself((s./Pyblosxom/pyblosxom.pysgetHttpÇs cCs |iSdS(s, Returns the _actual_ data dict. Holds run-time data which is created and transformed by pyblosxom during execution. Modifying the contents of the dict will affect all downstream processing. @returns: the run-time data dict @rtype: dict N(sselfs_data(sself((s./Pyblosxom/pyblosxom.pysgetDataÔs cCs|i|ƒdS(s Internal helper method for populating an existing dict with data from the new dict. @param currdict: the existing dict to update @type currdict: dict @param newdict: the new dict with values to update with @type newdict: dict N(scurrdictsupdatesnewdict(sselfscurrdictsnewdict((s./Pyblosxom/pyblosxom.pys__populatedictás cCs|i|i|ƒdS(sÅ Takes in a dict and adds/overrides values in the existing http dict with the new values. @param d: the dict with the new keys/values to add @type d: dict N(sselfs_Request__populatedicts_httpsd(sselfsd((s./Pyblosxom/pyblosxom.pysaddHttpîscCs|i|i|ƒdS(sÅ Takes in a dict and adds/overrides values in the existing data dict with the new values. @param d: the dict with the new keys/values to add @type d: dict N(sselfs_Request__populatedicts_datasd(sselfsd((s./Pyblosxom/pyblosxom.pysaddDataøscCs|i|i|ƒdS(sÚ Takes in a dict and adds/overrides values in the existing configuration dict with the new values. @param newdict: the dict with the new keys/values to add @type newdict: dict N(sselfs_Request__populatedicts_configurationsnewdict(sselfsnewdict((s./Pyblosxom/pyblosxom.pysaddConfigurationscCs^|dddgjo |iSn|djo |iSn|djo |iSnt|‚dS(Nsconfigs configurationsconfsdatashttp(snamesselfs_configurations_datas_httpsAttributeError(sselfsname((s./Pyblosxom/pyblosxom.pys __getattr__ s     cCsdSdS(s‚ Returns a representation of this request which is "Request". @returns: "Request" @rtype: string sRequestN((sself((s./Pyblosxom/pyblosxom.pys__repr__s(s__name__s __module__s__doc__s__init__s__iter__sbuffer_input_streams setResponses getResponses_Request__getformsgetFormsgetConfigurationsgetHttpsgetDatas_Request__populatedictsaddHttpsaddDatasaddConfigurations __getattr__s__repr__(((s./Pyblosxom/pyblosxom.pysRequest's"  3    sResponsecBsVtZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z RS( sÅ Response class to handle all output related tasks in one place. This class is basically a wrapper arround a StringIO instance. It also provides methods for managing http headers. cCs»||_tƒ|_t|_h|_d|_|ii |_ |ii |_ |ii |_ |ii |_ |ii |_ |ii|_|ii|_|ii|_|ii|_dS(sÜ Sets the L{Request} object that leaded to this response. Creates a L{StringIO} that is used as a output buffer. @param request: request object. @type request: L{Request} s200 OKN(srequestsselfs_requestsStringIOs_outsFalses _headers_sentsheaderssstatussclosesflushsreadsreadlines readlinessseekstellswrites writelines(sselfsrequest((s./Pyblosxom/pyblosxom.pys__init__)s     cCs |iSdS(sê Can't copy the __iter__ method over from the StringIO instance cause iter looks for the method in the class instead of the instance. See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252151 N(sselfs_out(sself((s./Pyblosxom/pyblosxom.pys__iter__AscCs ||_dS(sœ Sets the status code for this response. @param status: A status code and message like '200 OK'. @type status: str N(sstatussself(sselfsstatus((s./Pyblosxom/pyblosxom.pys setStatusJscCs |iSdS(sf Returns the status code and message of this response. @returns: str N(sselfsstatus(sself((s./Pyblosxom/pyblosxom.pys getStatusSscGsêt|ƒ}t|ƒd o¿xÅ|o°|idƒiƒ}|idƒdjp|idƒdjo td‚n|idƒiƒ}|i ƒdjo|i t |ƒƒq!|i ih|t |ƒ<ƒq!Wn td‚d S( sQ Populates the HTTP header with lines of text. Sets the status code on this response object if the given argument list containes a 'Status' header. @param args: Paired list of headers @type args: argument lists @raises ValueError: This happens when the parameters are not correct iis iÿÿÿÿs:s(There should be no spaces in header keyssstatuss,Headers recieved are not in the correct formN(slistsargsslenspopsstripskeysfinds ValueErrorsvalueslowersselfs setStatussstrsheaderssupdate(sselfsargssvalueskey((s./Pyblosxom/pyblosxom.pys addHeader[s  , (cCs |iSdS(s Returns the headers of this response. @returns: the HTTP response headers @rtype: dict N(sselfsheaders(sself((s./Pyblosxom/pyblosxom.pys getHeaderstsc Cs|id|iƒ|idigi}|iiƒD]!}|d||i|fƒq7~ƒƒ|idƒt |_ dS(s} Send HTTP Headers to the given output stream. @param out: File like object @type out: file s Status: %s s s%s: %ss N( soutswritesselfsstatussjoinsappends_[1]sheadersskeysshkeysTrues _headers_sent(sselfsouts_[1]shkey((s./Pyblosxom/pyblosxom.pys sendHeaders}s Q cCs>|idƒy|i|iƒƒWntj onXdS(s‚ Send the response body to the given output stream. @param out: File like object @type out: file iN(sselfsseeksoutswritesreadsIOError(sselfsout((s./Pyblosxom/pyblosxom.pyssendBodyŠs  ( s__name__s __module__s__doc__s__init__s__iter__s setStatuss getStatuss addHeaders getHeaderss sendHeadersssendBody(((s./Pyblosxom/pyblosxom.pysResponse"s     c Cs||iƒ} |iƒ}tidhd|»ss defaultfunccCstS(N(sNone(sx((s./Pyblosxom/pyblosxom.pys¼ssblosxomsPyblosxom.rendererss stdoutputistimezonespathinfosfilelists entry_listismtimes %a, %d %b %Ys latest_datesCs%Y-%m-%dT%H:%M:%SZslatest_w3cdates%a, %d %b %Y %H:%M GMTslatest_rfc822datesprepares logrequestsfilenameslogfiless return_codes200sStatuss 404 Not Foundstitles-The page you are looking for is not availablesbodys)Somehow I cannot find the page you want. sGo Back to %s?sbase_urls blog_titles404sContent-Type: text/plain s*There is something wrong with your setup. s-Check your config files and verify that your sconfiguration is correct. N(*srequestsgetConfigurationsconfigsgetDatasdatastoolss run_callbacksrendsgets importnamesRendererssyssstdoutstimestznames localtimesblosxom_process_path_infosblosxom_file_list_handlers entry_lists isinstanceslistslensmtimes mtime_tuplesgmtimes mtime_gmtuplesstrftimeslocales getlocalesLC_ALLslocs setlocalesrenderersrendereds setContents addHeadersrendersoutputswrites get_cachescachesclose( srequestslocs mtime_tuplescachesoutputsrendsmtimesdatas mtime_gmtuples entry_listsconfigsrenderer((s./Pyblosxom/pyblosxom.pysblosxom_handleržsl     %         #          25 .c Cs†|iƒ}h} t|dƒ}|iƒ}|i ƒt |ƒdjohdd<ddOss defaultfunccCsdi|dƒS(Nssstory(sjoinsx(sx((s./Pyblosxom/pyblosxom.pysPss postformats entry_dataN(srequestsgetConfigurationsconfigs entryDatasopensfilenamesfs readlinesslinesscloseslenspopsstripstitles startswithsmetassplitsgetsargsstoolss run_callbacksotmp( sfilenamesrequestsargssotmpsfslinesstitlesmetasconfigs entryData((s./Pyblosxom/pyblosxom.pysblosxom_entry_parsers2    #9    cCsû|d}|iƒ}|iƒ} |ddjo/ti||dt| i ddƒƒƒ}n)|ddjo|dg}ng}g}x:|D]2} t || |dƒ}|i|i|fƒq—W|iƒ|iƒ|do™|d tiiƒjoti|d p|d }d |d||d } gi}|D].} ti| | d iƒo|| ƒqJqJ~} n|} | i d dƒ}|o |d o| | } d|d Renders a url of your blog. %(script)s -r http://www.joesblog.com/cgi-bin/pyblosxom.cgi/index.html will pull off the base_url from the front leaving "/index.html" and will render "/index.html" to stdout. %(script)s -c ~/cgi-bin/config.py -r /index.html will use the config.py file located in ~/cgi-bin/ and render "/index.html" from the PyBlosxom root. -s, --static [incremental] Statically renders your blog. Use "incremental" to do an incremental rendering. -t, --test Tests your installation. EXAMPLES: Additional flags and options may be available through plugins that you have installed. Refer to plugin documentation (usually found at the top of the plugin file) for more information. cCs4|iƒ}dGHdGHdGHdtGHdtiiddƒGHdtiGHd |i d d ƒGHdGHd GHd t |ƒGHdGHdg} ddddddddddddddddd d!d"d#d$g}|i ƒ}|id%ƒ|id&ƒg} g} gi}| D]!}||jo||ƒq q ~} gi}|D]!}||jo||ƒqAqA~}|| }gi}|D]!}||jo||ƒqƒqƒ~}|iƒ| o@dGHd'GHd(GHdGHx| D]}d)|GHqÙWdGHd*GHd+Sn|o7dGHd,GHd-GHd.GHdGHx|D]}d/|GHq%Wn|o<dGHd0GHd1GHd2GHdGHx|D]}d3|GHqcWdGHnd4GHdGHd5GHtii|dƒ o)d6|dGHd7GHd8GHdGHd*GHd+Snd9GHd:GHd;GHdGHd<GH|idƒo3ti|d|i dtƒƒg} xÇti D]¼}t!|d=ƒo}d>|i"GHd?|i#GHd@t$t%|dAƒƒGHy(|i&|ƒdBjo dCGHndDGHWqät'j o}dEG|GHqäXq(|i"}|i#} | idF|| fƒq(Wt | ƒdGjo,dGHdHdIGHx| D]}dJ|GHqWq0ndKGHd+S(Ls• This function gets called when someone starts up pyblosxom.cgi from the command line with no REQUEST_METHOD environment variable. It: 1. tests properties in their config.py file 2. verifies they have a datadir and that it exists 3. initializes all the plugins they have installed 4. runs "cb_verify_installation"--plugins can print out whether they are installed correctly (i.e. have valid config property settings and can read/write to data files) 5. exits The goal is to be as useful and informative to the user as we can be without being overly verbose and confusing. This is designed to make it much much much easier for a user to verify their PyBlosxom installation is working and also to install new plugins and verify that their configuration is correct. @param request: the Request object @type request: object s8Welcome to PyBlosxom's installation verification system.s------s]] printing diagnostics [[spyblosxom: %sssys.version: %ss s sos.name: %sscodebase: %sscodebases --default--s]] checking config file [[sconfig has %s properties set.ssdatadirs blog_titles blog_authorsblog_descriptions blog_languages blog_encodings blog_icbmsbase_urlsdepths num_entriessrenderers cacheDrivers cacheConfigs plugin_dirss load_pluginss blog_emails blog_rightssdefault_flavours flavourdirslog_files log_levelslogdirspyblosxom_versionspyblosxom_names8Missing properties must be set in order for your blog toswork.s" missing required property: '%s's5This must be done before we can go further. Exiting.Ns=You're missing optional properties. These are not required, s?but some of them may interest you. Refer to the documentation sfor more information.s" missing optional property: '%s's9These are properties PyBlosxom doesn't know about. They s7could be used by plugins or could be ones you've added.s)Remove them if you know they're not used.s i don't know about: '%s'sPASS: config file is fine.s]] checking datadir [[sdatadir '%s' does not exist.s7You need to create your datadir and give it appropriates permissions.sPASS: datadir is there.s; Note: this does NOT check whether your webserver has s( permissions to view files therein!s4Now we're going to verify your plugin configuration.sverify_installations=== plugin: '%s's file: %ss version: %ss __version__is PASSs FAIL!!!s FAIL!!! s '%s' (%s)is2The following plugins do not support installation s verification:s %ss(You have chosen not to load any plugins.(+srequestsgetConfigurationsconfigs VERSION_DATEssyssversionsreplacesossnamesgetslensrequired_configsnice_to_have_configskeyss config_keyssremovesmissing_required_propssmissing_optionsal_propssappends_[1]smsmissing_optional_propssall_keysssortsmemspathsisdirshas_keys plugin_utilssinitialize_pluginssNonesno_verification_supportspluginsshasattrs__name__s__file__sstrsgetattrsverify_installationsAssertionErrors error_messagesmnsmf(srequestsmnsms config_keyssall_keyssnice_to_have_configsconfigsmissing_optional_propssmemsrequired_configsmissing_optionsal_propssmissing_required_propssmfsno_verification_supports error_messages_[1]((s./Pyblosxom/pyblosxom.pystest_installation‰sÀ    E   88 8              c CsÐd„}ti|ƒ}x–|D]Ž}|dddgjoM|d}|idƒo|dd!}n|d|ƒti i |ƒq|dd d gjo d „}qqW|d ƒyd k l }Wnd|GHdGHdSnX|idƒoti i |dƒn|dtƒt|ƒdjothd|<GHdSnt|hƒ}d}xe|D]]}|dddgjodSqg|dddgjotƒGHdSqg|dddgjo5|didƒo d} nd} |i| ƒqg|dddgjo d}qg|dddgjoh|d} | i|iddƒƒo | t|iddƒƒ} n|d| ƒ|i| |ƒqg|dd d!gjo|iƒqgqgWdSd"S(#sM Handles calling PyBlosxom from the command line. This can be called from two different things: pyblosxom.cgi and pyblcmd. @param scriptname: the name of the script (ex. "pyblcmd") @type scriptname: string @param argv: the arguments passed in @type argv: list of strings @returns: the exit code cCs |GHdS(N(ss(ss((s./Pyblosxom/pyblosxom.pysprintq:sis-cs--configis config.pyi÷ÿÿÿs0Appending %s to sys.path for config.py location.s-qs--quietcCs|S(N(ss(ss((s./Pyblosxom/pyblosxom.pysIss&Trying to import the config module....(spys>Error: Cannot find your config.py file. Please execute %s in s-the directory with your config.py file in it.scodebasesPyBlosxom version: %ssscripts-vs --versions-hs--helps--statics-ssincrs --headerss--renders-rsbase_urlssRendering '%s's--tests-tN(sprintqstoolss parse_argssargvsoptlistsmemsmsendswithssysspathsappendsconfigspyscfgs scriptnameshas_keys VERSION_DATEslensHELPs PyBlosxomspsheaderssget_helps startswiths incrementalsrunStaticRenderersurlsgets runRenderOnestestInstallation( s scriptnamesargvsprintqsheaderssmemscfgsmsoptlistsps incrementalsurl((s./Pyblosxom/pyblosxom.pyscommand_line_handler-sf         (&s __future__s nested_scopess generatorss __revision__sosstimesreslocalessyssos.pathscgis cStringIOsStringIOs ImportErrorstoolss plugin_utilssentries.fileentrys FileEntrysVERSIONs VERSION_DATEstuplessplits VERSION_SPLITs PyBlosxomsPyBlosxomWSGIAppspyblosxom_app_factorysdictsEnvDictsobjectsRequestsResponsesblosxom_handlersblosxom_entry_parsersblosxom_file_list_handlersblosxom_process_path_infosHELPstest_installationscommand_line_handler(sHELPslocalesblosxom_handlers FileEntrys VERSION_SPLITstoolsscommand_line_handlers __revision__sblosxom_entry_parsersblosxom_process_path_infosresEnvDicts generatorssResponsesPyBlosxomWSGIAppscgis nested_scopessRequestsblosxom_file_list_handlerssyssVERSIONs VERSION_DATEs PyBlosxomsStringIOspyblosxom_app_factorys plugin_utilsstimestest_installationsos((s./Pyblosxom/pyblosxom.pys?sB           ÿ‘/ *û|  > = ³> ¤