; )HEc @sSdklZdkZdkZdkZdkZdklZlZlZdk Tdk Z dk l Z l Z dklZlZdklZdklZdklZd klZlZlZd klZlZlZd kl Z ei!hd ed d <dedd <dedd <dedd <dedd <dedd <dedd <dgZ"dddddgZ#dddgZ$dddd d!d"d#d$d%g Z%d&d'd(d)d*d+d,gZ&xe&D]Z'ee'qWd-fd.YZ(ee(ee(d/k)l*Z*l+Z+ee*e(i,ee+d0dS(1(s nested_scopesN(sjoinssplitsstrip(s*(sgetSecurityManagersClassSecurityInfo(sInitializeClasss package_home(sregisterPlugin(sregisterPageMetaData(s Permissions(sBLATHERsformattedTracebacksaddHook(sloadDtmlMethodsloadPageTemplates TEMPLATES(s_sissuepropertiesformsplugins/trackers issuetrackers issuebrowsers filterissuess IssueTrackers IssueBrowsers FilterIssuessgeneralscriticalsserioussnormalsminorswishlistsopenspendingscloseds,open,critical ,#ff2222s,open,serious ,#ff9090s,open,normal ,#ffbbbbs,open,minor ,#ffdddds,open,wishlist ,#e0e0e0s,open, ,#ffe0e0s,pending, ,#ffcc77s,closed, ,#bbeebbs,, ,scategoryscategory_indexsseveritysseverity_indexsstatuss status_indexs issueColours PluginTrackerc BstZdZeZeieiddZeieiddZ eieide dZ eieiddZ eieid d Z eieid d Zeieid dZdZeieiddZeieiddZeieiddZddZddZeieiddde ddde ddZeieidddddde ddZeieide dZeieid e e e e e de d!Zd"Zd#Zd$Zeieid%e d&Zeieid'e d(Z eieid)e d*Z!eieid+d,Z"eieid-d.Z#eieid/dddd0Z$eieid1e d2Z%eieid3d4Z&eieid5d6Z'eieid5d7Z(eid8d9e d:d;Z)d<Z*d=Z+RS(>sg This mix-in class adds some methods to ZWikiPage to facilitate wiki-based issue trackers. s hasIssuescCs|idjSdS(s8 True if this wiki has any issue pages. iN(sselfs issueCount(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys hasIssuesSss issueCountcs#ttdiSdS(s9 The number of issue pages in this wiki. cs i|S(N(sselfsisIssuesx(sx(sself(sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys^sN(slensfiltersselfs pageNames(sself((sselfsG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issueCountZssisIssuecCs8|i|p |ipt|idodSdS(sW True if this page (or another named page) represents a tracker issue. sstatusiN(sselfsissueNumberFromspagenamespageNameshasattrsaq_base(sselfspagename((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysisIssueass issueNumbercCs(|i|i}|o|dSdS(s4 This page's issue number, or None. iN(sselfsissueNumberAndNameFromspageNames numberandname(sselfs numberandname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issueNumberlss issueNamecCs(|i|i}|o|dSdS(sH This page's issue name (the non-number part), or None. iN(sselfsissueNumberAndNameFromspageNames numberandname(sselfs numberandname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issueNametssissueNumberFromcCs"|i|}|o|dSdS(sE Extract the issue number from a page name, or None. iN(sselfsissueNumberAndNameFromspagenames numberandname(sselfspagenames numberandname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysissueNumberFrom|ss issueNameFromcCs"|i|}|o|dSdS(sH Extract the issue name part from a page name, or None. iN(sselfsissueNumberAndNameFromspagenames numberandname(sselfspagenames numberandname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issueNameFromscCsdSdS(s8Should issue page names start with just # in this wiki ?iN((sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysshortIssueNamesEnabledssissueNumberAndNameFromcCsytid|p|iotid|}|o,t|id|idifSnt |ifSdS(sy Extract issue number and issue name from a page name if possible. Returns a tuple of (issuenumber, issuename) strings, or (None, pagename) if no issue number can be found. The issue name is stripped of surrounding whitespace. Should be able to parse the format generated by pageNameFromIssueNumberAndName, and other common formats for compatibility For example: IssueNoN ISSUENAME IssueNoN and when short_issue_names is enabled: #N ISSUENAME #N where N is one or more digits and ISSUENAME is any text. s(?s)^IssueNo([0-9]+)(.*)s(?s)^#([0-9]+)(.*)iiN( sresmatchspagenamesselfsshortIssueNamesEnabledsmsintsgroupsstripsNone(sselfspagenamesm((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysissueNumberAndNameFroms 2,spageNameFromIssueNumberAndNamecCs5|io|i||Sn|i||SdS(sE Make a page name from an issue number and issue name. This method controls the naming of new issue pages. There are currently two variants, controlled by the short_issue_names folder property. It should be parseable by issueNumberAndNameFrom. Expects number:int, name:str. N(sselfsshortIssueNamesEnabledsshortIssueNameFromsnumbersnameslongIssueNameFrom(sselfsnumbersname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pyspageNameFromIssueNumberAndNames sissuePageWithNumbercCsft|tjotSn|i|i|ddddp"|i|i|ddddSdS(s Return the issue page with the specified issue number, or None. Tries both the short and long issue page name formats; should match issueNumberAndNameFrom. It's harmless to call this with a non-number. s allow_partialis numeric_matchN(stypesnumbersIntTypesNonesselfspageWithFuzzyNamesshortIssueNameFromslongIssueNameFrom(sselfsnumber((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysissuePageWithNumbersscCs'|tjod||fSn|SdS(s Make up an issue page name from the issue number & description. (name here means the text part, ie the issue description). If number is None, just returns name unchanged. s#%d %sN(snumbersNonesname(sselfsnumbersname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysshortIssueNameFroms cCsd||fSdS(NsIssueNo%04d %s(snumbersname(sselfsnumbersname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pyslongIssueNameFromss createIssueic Cs|ido dg} ng} |i|d|d|d| d|} | or|i|} | i ddd| i d d d| i d d d| i d |d|d |d || SntSdS(s Create a page representing an issue with the specified details. Security notes: sets title/category/severity/status properties without requiring Manage properties permission. create() will also check the edits_need_username property and redirect us to /denied if appropriate. We try to place the issue under a suitable parent - the IssueTracker page if it exists, or at the top level to avoid having issues scattered everywhere. Better ideas ? Returns the new page name or None. XXX clean up old args kept for backwards compatibility. Only really old issue tracker dtml pages call this directly. pageid is really pagename. title is not used. s IssueTrackerstextsREQUESTsparentsssendmailscategorysissue_categoriess selectionsseveritysissue_severitiessstatussissue_statusesstitleN(sselfs pageWithNamesparentsscreatespageidstextsREQUESTssendmailsnamesissuesmanage_addPropertysmanage_changePropertiesscategorysseveritysstatussNone( sselfspageidstextstitlescategorysseveritysstatussREQUESTssendmailsparentssissuesname((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys createIssues"    screateNextIssuec Cs||id|}|i||} |i| |t |||||} | o%|o|ii|iqtn| SdS(sV Add a new issue page, using the next available number, and redirect. createIssue() (really create()) will also check the edits_need_username property and may redirect to an error. Otherwise this will redirect to the tracker url (when called via the web). Returns the new page's name or None. sREQUESTN(sselfsnextIssueNumbersREQUESTs newnumberspageNameFromIssueNumberAndNamesnamespagenames createIssuestextsNonescategorysseveritysstatusssendmailsRESPONSEsredirects trackerUrl( sselfsnamestextscategorysseveritysstatussREQUESTssendmails newnumberspagename((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pyscreateNextIssue s snextIssueNumbercCsfgi}|iddd|D]}||i|iq ~}|i dg|ddSdS(s; Get the next available issue number. Adds one to the current highest issue number, so gaps are allowed. Handles both old and new-style issue page names. Does a catalog search, so REQUEST may be required to authenticate and get the proper results. I think. sisIssueisREQUESTiiN( sappends_[1]sselfspagessREQUESTsbsissueNumberFromsTitles issuenumbersssort(sselfsREQUESTs_[1]sbs issuenumbers((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysnextIssueNumbers E schangeIssuePropertiesc Cs|i| o|itdSnd} |o||ijo|i|i |} | d|i | f7} |i t i| odtdn|i| dddd d |qn|out|d d}||joR| d ||f7} |i t i| odtd n|id |qGn|out|dd}||joR| d||f7} |i t i| odtd n|id|qn|out|dd}||joR| d||f7} |i t i| odtd n|id|q?n|o| d|7} n| oe|i t i| odtdnd} |o| |7} n|id| d| d |n|o|ii|indS(s Change an issue page's properties and redirect back there. Also, add a comment to the page describing what was done. Optionally a comment subject and body can be set. name is the issue name excluding the issue number. Changing this will trigger a page rename, which may be slow. Security: allows modification of some properties (title/category/severity/status) with zwiki edit permission rather than zope Manage properties permission. Upgrade issue: calling this before upgrading an issue to a 0.17-style page id will mess up the id/title. s]Sorry, this wiki doesn't allow anonymous edits. Please configure a username in options first.ssName: '%s' => '%s' s Unauthorizeds1You are not authorized to rename this ZWiki Page.supdatebacklinksissendmailisREQUESTscategorysCategory: %s => %s s/You are not authorized to edit this ZWiki Page.sseveritysSeverity: %s => %s sstatussStatus: %s => %s s s5You are not authorized to comment on this ZWiki Page.stextssubject_headingN(sselfscheckSufficientIdsREQUESTsdenieds_scommentsnames issueNamespageNameFromIssueNumberAndNames issueNumbers newpagenamespageNamescheckPermissions PermissionssRenamesrenamescategorysgetattrsoldsEditsmanage_changePropertiessseveritysstatusstextsCommentssubjectslogsRESPONSEsredirectspageUrl( sselfsnamescategorysseveritysstatusslogstextsREQUESTsoldssubjectscomments newpagename((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pyschangeIssueProperties-s^     cCsEy!dt|ii|iSWnttfj o dSnXdS(s3helper method to facilitate sorting catalog resultsiiN(slistsselfsissue_categoriessindexscategorysAttributeErrors ValueError(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pyscategory_indexys !cCsEy!dt|ii|iSWnttfj o dSnXdS(s3helper method to facilitate sorting catalog resultsiiN(slistsselfsissue_severitiessindexsseveritysAttributeErrors ValueError(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysseverity_indexs !cCsEy!dt|ii|iSWnttfj o dSnXdS(s3helper method to facilitate sorting catalog resultsiiN(slistsselfsissue_statusessindexsstatussAttributeErrors ValueError(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys status_indexs !s issuetrackercCs|id||SdS(sG Render the issuetracker form (template-customizable). s issuetrackerN(sselfsgetSkinTemplatesREQUEST(sselfsREQUEST((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issuetrackerss filterissuescCs|id||SdS(sG Render the filterissues form (template-customizable). s filterissuesN(sselfsgetSkinTemplatesREQUEST(sselfsREQUEST((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys filterissuesss issuebrowsercCs|id||SdS(sG Render the issuebrowser form (template-customizable). s issuebrowserN(sselfsgetSkinTemplatesREQUEST(sselfsREQUEST((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issuebrowserssaddIssueFormTocCs3t|dt}|i|id||SdS(sJ Add an issue property form above the rendered page text. sREQUESTN(sgetattrsselfsNonesREQUESTs stxToHtmlsissuepropertiesformsbody(sselfsbodysREQUEST((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysaddIssueFormToss issueColourcCs_|itt|d|ddtt|d|ddtt|d|ddSdS(sB Tell the appropriate issue colour for this page. saq_basescategoryssseveritysstatusN(sselfsissueColourForsgetattr(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys issueColours!sissueColourForc sjtdf\t|idt}t d|}g}xf|D]^}td|i d\} }}} |ihd| <d|<d|<d| <q[W|o&t d|pt d |}|o&t d |pt d |}|o&t d |pt d |}| odSn |ddSdS(sl Choose an issue colour based on issue properties. Finds the best match in a list of strings like "category,status,severity,colour", any of which may be empty. The defaults can be overridden with an 'issue_colours' folder lines property. If no match is found in the colour list, returns the empty string. cCs |iS(N(sxsstrip(sx((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysss issue_colourss,scategorysstatussseverityscolourcs|djS(Nscategory(sxscategory(sx(scategory(sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysscCs|ddjS(Nscategorys(sx(sx((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysscs|djS(Nsstatus(sxsstatus(sx(sstatus(sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysscCs|ddjS(Nsstatuss(sx(sx((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysscs|djS(Nsseverity(sxsseverity(sx(sseverity(sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysscCs|ddjS(Nsseveritys(sx(sx((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysssiN(smapscategorysstatussseveritysgetattrsselfsfolders ISSUE_COLOURSscolourssfilterslsissplitsasbscsdsappend( sselfscategorysseveritysstatusscsbsislscolourssasd((scategorysseveritysstatussG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysissueColourFors  '5///sissuepropertiesformcCs|id||SdS(sU Render the issue properties form as a (customizable) HTML fragment. sissuepropertiesformN(sselfsgetSkinTemplatesREQUEST(sselfsREQUEST((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysissuepropertiesformss trackerUrlcCs|iddSdS(Ns IssueTrackers issuetracker(sselfsurlForDtmlPageOrMethod(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys trackerUrlss filterUrlcCs|iddSdS(Ns FilterIssuess filterissues(sselfsurlForDtmlPageOrMethod(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys filterUrlscCs|iddSdS(Ns IssueBrowsers issuebrowser(sselfsurlForDtmlPageOrMethod(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysissueBrowserUrlssManage propertiess setupTrackeric Csg}ddddddddg} g}g}g}|id d |i} | i| i f\} }| i d }x-|D]%} | | j o|i| qqWx-| D]%} | | j o|i| qqWx-|D]%} | | j o|i| qqWx-|D]%} | | j o|i| qqWx-|D]%} | | j o|i| qDqDW|i|ott}xgd d dgD]V}|i| o?|i|dttii||ddi dd qqW|i!i"d nd }|ii$} xy|i&D]k}|d}y1t(d||i)| f|i*dd Wq0t(d||i)t+fq0Xq0Wt(d||i, o/|i-ddt.dt/dt0dd|n|o|i2i3|i4ndS(s Configure this wiki for issue tracking. This - sets up the necessary extra catalog fields - sets up issue_* folder properties, for customizing - creates a dummy issue, if needed, to activate the issue links/tabs - if pages=1, installs forms as DTML pages, for easy customizing Safe to call more than once; will ignore any already existing items. scategoryscategory_indexsisIssues issueNumbersseveritysseverity_indexsstatuss status_indexsreindexis PluginIndexess IssueTrackers FilterIssuess IssueBrowserstexts.dtmlsrssendmailisindexing page #%d %s in %sslogsfailed to index page #%d %s: %ss%indexing complete, %d pages processeds first issuesSThis issue was created to activate the issue tracker links/tabs. You can re-use it.isREQUESTN(5s TextIndexess FieldIndexessKeywordIndexess DateIndexess PathIndexessselfs setupCatalogscatalogsindexessschemascatalogindexesscatalogmetadatasmanage_addProducts PluginIndexessismanage_addTextIndexsmanage_addFieldIndexsmanage_addKeywordIndexsmanage_addDateIndexsmanage_addPathIndexsupgradeFolderIssuePropertiesspagess package_homesglobalssdirspages pageWithNamescreatesopensosspathsjoinsreads IssueTrackerssetSubtopicsPropertyStatussnsgetIdscids pageObjectsspsBLATHERsids index_objectsformattedTracebacks hasIssuesscreateNextIssuesISSUE_CATEGORIESsISSUE_SEVERITIESsISSUE_STATUSESsREQUESTsRESPONSEsredirects trackerUrl(sselfsREQUESTspagess TextIndexess DateIndexesscatalogmetadatasnsKeywordIndexess PathIndexesscatalogs FieldIndexesscidsiscatalogindexesspsdirspages PluginIndexes((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys setupTrackersx      (  ( cCs|i}td|i}xfdtgdtgdtgdtggD]:\}}||j o |i |t |ddqLqLWdS( s Upgrade issue tracker related properties on the wiki folder if needed. Currently just adds properties if missing. cCs|dS(Nsid(sx(sx((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysUssissue_categoriessissue_severitiessissue_statusess issue_colourss slinesN( sselfsfoldersmaps _propertiess existingpropssISSUE_CATEGORIESsISSUE_SEVERITIESsISSUE_STATUSESs ISSUE_COLOURSspropsvaluessmanage_addPropertysjoin(sselfspropsvaluess existingpropssfolder((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysupgradeFolderIssuePropertiesNs + cCsd}|io|itd|i}xddtgdddgdd tggD]U\}}}||j o8|i ||d |ot |||nd }q]q]Wn|Sd S( s Upgrade tracker related properties on this page (and folder) if needed. Returns non-zero if we changed any page properties, to help upgrade() efficiency. icCs|dS(Nsid(sx(sx((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysksscategorysissue_categoriessseveritysissue_severitiessnormalsstatussissue_statusess selectioniN( schangedsselfsisIssuesupgradeFolderIssuePropertiessmaps _propertiess existingpropssNonespropsvaluessdefaultsmanage_addPropertyssetattr(sselfsdefaultschangedspropsvaluess existingprops((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pysupgradeIssueProperties_s  +(,s__name__s __module__s__doc__sClassSecurityInfossecuritysdeclareProtecteds PermissionssViews hasIssuess issueCountsNonesisIssues issueNumbers issueNamesissueNumberFroms issueNameFromsshortIssueNamesEnabledsissueNumberAndNameFromspageNameFromIssueNumberAndNamesissuePageWithNumbersshortIssueNameFromslongIssueNameFromsAdds createIssuescreateNextIssuesnextIssueNumbersEditschangeIssuePropertiesscategory_indexsseverity_indexs status_indexs issuetrackers filterissuess issuebrowsersaddIssueFormTos issueColoursissueColourForsissuepropertiesforms trackerUrls filterUrlsissueBrowserUrls setupTrackersupgradeFolderIssuePropertiessupgradeIssueProperties(((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys PluginTrackerKsx              !* L        &    X (s upgrade_hookssupgradeId_hookscCs|i|i|iS(N(sselfspageNameFromIssueNumberAndNames issueNumbers issueName(sself((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pyss(-s __future__s nested_scopessossstringsresos.pathsjoinssplitsstripstypessDocumentTemplates AccessControlsgetSecurityManagersClassSecurityInfosGlobalssInitializeClasss package_homesProducts.ZWiki.pluginssregisterPluginsProducts.ZWiki.DefaultssregisterPageMetaDatasProducts.ZWikis PermissionssProducts.ZWiki.UtilssBLATHERsformattedTracebacksaddHooksProducts.ZWiki.ViewssloadDtmlMethodsloadPageTemplates TEMPLATESsProducts.ZWiki.I18ns_supdatesISSUE_CATEGORIESsISSUE_SEVERITIESsISSUE_STATUSESs ISSUE_COLOURSsTRACKER_METADATAsas PluginTrackersProducts.ZWiki.Admins upgrade_hookssupgradeId_hookssupgradeIssueProperties(sISSUE_CATEGORIESsformattedTracebacksloadDtmlMethodsregisterPageMetaDatasaddHooksstrips TEMPLATESsupgradeId_hookssressplitsloadPageTemplates PluginTrackers PermissionssISSUE_SEVERITIESsstrings nested_scopessClassSecurityInfosInitializeClasss upgrade_hookssregisterPluginsISSUE_STATUSESs_sasBLATHERsjoinsgetSecurityManagers ISSUE_COLOURSsTRACKER_METADATAsDocumentTemplatesoss package_home((sG/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/plugins/tracker/tracker.pys?s< $      !  .