o ]LbBP@sddlmZddlZddlZddlZddlmZddlmZm Z m Z m Z m Z m Z mZmZmZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ m!Z!ddlm"Z"m#Z$m%Z%m&Z&dd l'm(Z(d d Z)d d Z*ddZ+ddZ,dddZ-ddZ. dddZ/Gddde0Z1dS))absolute_importN)_) ErrorResponseHTTP_SERVER_ERROR cspvalues get_contact get_mtimeismember paritygen staticfile statusmessage) configitemsencodingerror extensionshgpathutil profilingpycompatrcutil registrarscmutil templater templateutiluiutil) hgweb_modrequestwebutilwsgicgi)dateutilcCsdd|DS)NcSs$g|]\}}t|d|fqS)/)rpconvertstrip).0namepathr)>/usr/lib/python3/dist-packages/mercurial/hgweb/hgwebdir_mod.py 9s$zcleannames..r))itemsr)r)r* cleannames8sr-c Csg}t|D]@\}}tj|\}}z ddd|}Wnty+|||fYqwtjt|}t j |d|d}| t |||q|S)NFT)*s**) followsymrecurse) r-osr(splitKeyErrorappendnormpathrabspathr walkreposextendurlrepos)pathsreposprefixrootrootheadroottailr0r)r)r* findrepos<s r@ccsL|D] }tj|}|dt|t|ddd|fVqdS)ayield url paths and filesystem paths from a list of repo paths >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq] >>> conv(urlrepos(b'hg', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt'])) [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')] >>> conv(urlrepos(b'', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt'])) [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')] r#N)r1r(r5rr$lenlstripr%)r<r>r:r(r)r)r*r9Os "r9cCsV|j}|jdddd}|r|rt|||rdS|jdddd}|r't|||r)dSdS)aCheck allow_read and deny_read config options of a repo's ui object to determine user permissions. By default, with neither option set (or both empty), allow all users to read the repo. There are two ways a user can be denied read access: (1) deny_read is not empty, and the user is unauthenticated or deny_read contains user (or *), and (2) allow_read is not empty and the user is not in allow_read. Return True if user is allowed to read the repo, else return False.webs deny_readT untrustedFs allow_read) remoteuser configlistr )rrequser deny_read allow_readr)r)r* readallowed_s rLc#st|dd}|dd}t}t}|D]\}} ||s q|t|d}d} d|vrv|s1q|d} | d} |s=n9| |vrBq| |vrGn/d} | }d| dd} | dt|  d} z t|| d} Wn tt j fyuYnw|j d| d| dg}ddd d |Dd}| rz t | tdf}Wn tyYqwd d |d||d d ||d|dtgdtjgd d d }|||Vq|trz tj| ddWnty}ztd| |fWYd}~qd}~wwtjffdd }jddddrqt |s"qzt|| }Wn&ty=td| Yqt j yPtd| Yqwz t |j!tdf}Wn tyhYqwt"|}|dd}|||dd|}j#dddd}|pd|$pd||||pd|$pd||d|dt%&d|dtj|d d d }|VqdS)NrCsdescendscollapseFr#rTrcss|]}|r|VqdSNr))r&pr)r)r* sz"rawindexentries..rMslabel)r') contacts contact_sortnames name_sorturl descriptionsdescription_sort lastchangeslastchange_sortsarchivess isdirectorylabelss.hgshgrcserror reading %s/.hg/hgrc: %s csj|||ddS)NTrD)config)sectionr'defaultur)r*getszrawindexentries..getshiddenrDs!error accessing repository at %s rTrRrVsunknownstip)' configboolset startswithrAr2joinr repositoryIOErrorr RepoErrorapppathr%r r"makedateOSErrorr mappinglist hybridlistaddcopyr use_repo_hgrc readconfigr1r( Exceptionwarnruimod_unsetrLspathr rGupperr archivelist)rr;rHsubdirdescendcollapse seenreposseendirsr'r( directory namepartsrootname discardedpartsurldrower\rcontact descriptionlabelsr)rZr*rawindexentriesvs                   rc #snt||||d}d} |r"| ||fkr"d|t|fdd|d}t|t|D] \} } | | d<| Vq)dS)NrtNFs%s_sortcs|SrNr))xsortkeyr)r*sz"_indexentriesgen..)keyreversesparity)rsortedzipr ) contextrr;rH stripecount sortcolumn descendingrtrows sortdefaultrparityr)rr*_indexentriesgensrFcCs |||||||f}tjt|dS)N)args)rmappinggeneratorr)rr;rHrrrrtrr)r)r* indexentries src@sTeZdZdZdddZddZddZd d Zd d Zd dZ dddZ ddZ dS)hgwebdirzHTTP server for multiple repositories. Given a configuration, different repositories will be served depending on the request path. Instances are typically used as WSGI applications. NcCsP||_||_d|_d|_d|_|d|_|s&t|jt |jdSdS)Nr) confbaseuir lastrefreshmotdrefreshrequests_countrloadall populateui)selfrrr)r)r*__init__s zhgwebdir.__init__c Cs|jr |jdd}n tjdd}|j}|dkr$|j|tkr$dS|jr-|j}nt j }| dddd| ddd d| d d d d t |j tttfsd di}tj|j shttd|j |j|j |ddg}|dD]\}}|d|D] }|||fqqxnt |j ttfr|j }n t |j tr|j }t|t|} |dD]5\} } t| } t j!| ddD]$}tj"|} t| }|#| r|t$| d}| |%d| fqq| |_&||_|jdd|_'d|_(|j)ddt*_*|j)dd|_+|jj)dddd|_,|j)dd|_-|j-r&t.|j-|_-|j)dd} | #dr9| dd} | /drE| dd} | |_0t|_dS) NrCsrefreshintervalrsuisreport_untrustedsoffshgwebdirsnonttystruesprogresssdisableshgwebspathss hgweb-pathssconfig file %s not found!T)remaptrusts collections)r/r#s experimentals web.full-garbage-collection-rateencodingstyles templatesFrDsstripessprefixr)1r configintr coreitemsrYrtimerrjroload setconfig isinstancerdictlisttupler1r(existsrAbortrrlrGr4r,rrr@rr$rr7r5r_rArBr;gc_full_collect_rategc_full_collections_donerWrstyle templatepathrintendswithr<) rrefreshintervalitemr[mapr:r'ignoredr(r;r<r=repor)r)r*r&sx              zhgwebdir.refreshcCs*tjdddstdt|dS)NsGATEWAY_INTERFACErMsCGI/1.sJThis function is only intended to be called while running as a CGI script.)renvironr\r_ RuntimeErrorr!launchrr)r)r*runmsz hgwebdir.runcCs4|jdd}tj||d}t||}|||S)NrCbaseurl) altbaseurl)rrW requestmodparserequestfromenv wsgiresponserun_wsgi)renvrespondbaseurlrHresr)r)r*__call__ws  zhgwebdir.__call__c cs|jdd}tj|j|doz5|||D]}|VqW|j}|jd7_|dkr@|j|dkr@t|j d7_ n7tjddn(|j}|jd7_|dkrh|j|dkrht|j d7_ wtjddwWddSWddS1swYdS)Ns profilingsenabled)enabledrr) generation) rr]rprofile_runwsgirrgccollectr)rrHrrrrater)r)r*r~s,"zhgwebdir.run_wsgic sz}zI|t|j\}}|r||jd<|jd|||}|ddtji}d|_ ||jd< ds=d|j vrf drId d}n|j d}|jj d dd d }t |j||||WW~St|j} rqd kr| vr||||WW~Sdr| vrdtd  tfdd| Dr||||WW~Sfdd} | D]n} | | } | r|j} tjrddt| D} tj| | |j d d|jd}zt|j | }t!"|#||WWW~St$y }z t%|j&}t't(|d}~wt)j*y}zt't(t+|d}~wwqdfdd| Dr8||||WW~Sd|_ |,|-ddi|WW~St'y~}z%t.|j/t0||_ |,|-dd|j1pjdi|WYd}~W~Sd}~ww~w)NsContent-Security-Policyr#smimetypers200 Script output followss Content-Typesstatic/sstaticrCFrDindexs/indexc3s|]}|VqdSrNr_r&rrr)r*rPsz$hgwebdir._runwsgi..c3s"VtD]}|Vq dSrN)rfinddirs)rO)virtualr)r* _virtualdirss z'hgwebdir._runwsgi.._virtualdirscSsi|] \}}|d|qS)latin1)decode)r&kvr)r)r* s z%hgwebdir._runwsgi..r)reponamerbodyfhcsg|] }|r|qSr)rrrr)r*r+sz%hgwebdir._runwsgi..s 404 Not FoundsnotfoundsreposerrorrM)2rrrheaders dispatchpathr%rrenderrstatusr_qsparamsrWr r sendresponserr; makeindexrrAanyr\rawenvrispy3 iteritemsrrrrrarjrhgwebrrb strtolocalstrerrorrrrrcbytes setbodygengeneratercodebytestrmessage)rrHrcspnoncetmplctypefnamestaticr;r virtualreporealuenvrinstmsgrr))rtrr*rs       D =6       zhgwebdir._runwsgirMc s|gd}d\d|jvr)|jddr#dd|vr)dfdd|D}|t|j|j||j|d }||td ||j d }| || | d || S) N)rRrTrQrUrssort-rrMcs2g|]}d|d r|krdpd|ffqS)ssort_%ss%s%srrMr))r&columnrrr)r*r+s z&hgwebdir.makeindex..)rrrtr#)sentriesssubdirspathdefs sortcolumns descendingr)rrr_rrr;rrmakebreadcrumbr<updaterrr) rrHrrrtsortablesortentriesmappingr)rr*rs@         zhgwebdir.makeindexc sfddi}t|j\}\}}}||dkr||d<t|d}dd} dd} dd p;|jd d } | d sE| d 7} tj|jd | | | |||d } t | } | d ddfdd}t j j ||| dS)Ncs|ddjj|i|S)NrET) setdefaultrrW)rkwargsrr)r*rW+s z"hgwebdir.templater..configrr?rClogourllogoimg staticurlr#s/static/)rrSrrrs sessionvarsrsnoncemotdr))requiresc3s(jdur jVdSddVdS)NrCr)r)rrrWrr)r*rLs  z hgwebdir.templater..motd)fpdefaults) rgetstylerr sessionvarsrdrstriprrrtemplatekeywordr frommapfile)rrHrvarsstylesrmapfilerrlogourllogoimg staticurlrrrr)rr*r*s<        zhgwebdir.templaterrNrM) __name__ __module__ __qualname____doc__rrrrrrrrr)r)r)r*rs  G  ^ /rr%)rMFrM)2 __future__rrr1ri18nrcommonrrrr r r r r rrrrrrrrrrrrrrrrorrrrr r!utilsr"r-r@r9rLrrrobjectrr)r)r)r*s&  ,D