;ò < ÄDc@sdkZdkZdklZdkiZdkiZdkTdki Z dk i Z de fd„ƒYZ de ifd„ƒYZeZdS(N(s BeautifulSoup(s*s TrackerErrorcBstZRS(N(s__name__s __module__(((s./Sourceforge/plugin.pys TrackerError)ss SourceforgecBs_tZdZeZdgZdgZeiei BZ ei de ƒZ dZ hdd<dd<d d <d d <d d\s+([^<]+)\s+sZ&set=custom&_assigned_to=0&_status=%s&_category=100&_group=100&order=artifact_id&sort=DESCsanyidsopenisclosedisdeletedispendingiss http://sourceforge.net/projects/s/http://sourceforge.net/support/tracker.php?aid=cCs&tt|ƒ|_|ii|ƒdS(N(ssupers Sourceforgesselfs_Sourceforge__parents__init__sirc(sselfsirc((s./Sourceforge/plugin.pys__init__?scCs;|dddfjo|idƒSn|ii|ƒSdS(NsbugsrfespatchsenableSpecificTrackerCommands(snamesselfs registryValues_Sourceforge__parents isCommand(sselfsname((s./Sourceforge/plugin.pys isCommandCsccsƒx|tt|ii|ƒƒD]_}|idƒo+ti |dƒt i i |dƒfVq|dt i i |dƒfVqWdS(sw Parses the Sourceforge query to return a list of tuples that contain the tracker information. sboldiiN( sfiltersNonesselfs_infoResfindallstextsitems registryValuesircutilssboldsutilsswebs htmlToText(sselfstextsitem((s./Sourceforge/plugin.pys _formatRespIs +c Cs y#tiid|i|fƒ}Wn-tiij o}t it |ƒ‚nXt |ƒ}t idƒ}t id|iƒt iƒ} |ddƒdidhd|<ƒ} |i|i|} d | }xF| D]5} | i| iƒo|tii| dƒSqÚqÚWtd ‚d S( sV Searches the project's Summary page to find the proper tracker link. s%s%sstracker.*;atids^%s$sdivstopnavisashrefshttp://sourceforge.net%%s%ssInvalid Tracker pageN( sutilsswebsgetUrlsselfs _projectURLsprojectstextsErrorses callbackssstrs BeautifulSoupssoupsrescompileslinkResTypesstripsIstypeResulstrackerss _hrefOptss _statusOptsstatussoptssurlstrackerssearchsstrings htmlToTexts TrackerError( sselfsprojectsTypesstatusseslinkRessoupsurlstextstrackersstypeRestrackersopts((s./Sourceforge/plugin.pys_getTrackerURLUs # (  c Csytii|ƒ}Wn-tiij o}tit|ƒ‚nXd|jo d|Snd}gi }|i|ƒD]}|t||Œƒq|~}|o:t|ƒdjotd„|ƒ}ntd|ƒSntid|tiiiƒf‚dS( sT Searches the tracker list page and returns a list of the trackers. sNo matches found.sNo %s were found.s#%i: %si cCstii|dƒS(Ni2(sutilssstrs ellipsisifyss(ss((s./Sourceforge/plugin.pyswss%LsNo %s were found. (%s)N(sutilsswebsgetUrlsurlstextsErrorses callbackssstrstypesheadsappends_[1]sselfs _formatRespsentrysformatsrespslensmapsconfssupybotsrepliess possibleBug( sselfsurlstypesheadsestextsresps_[1]sentry((s./Sourceforge/plugin.pys_getTrackerListis  9sDetail:\s*(\d+)\s*-\s*(\w.*)satidcCs•ytii|ƒ}Wn*tiij o}tt|ƒ‚nXt |ƒ} |i dƒ} g}d}|ii| iiƒ}| dhdd<ƒd}|idhd|i<ƒi}|o|ostii|ƒ}|iƒ\}}| o"td ti |ƒ||ƒ}ntd |||ƒ}|i|ƒnt S| id ƒ}h} t#i$d ƒ}x’|d ƒD]„} | i'io,| i(i)i*d ƒ| | i'ii+dƒ Returns a description of the bug with id . Really, this is just a wrapper for the tracker command; it won't even complain if the you give isn't a bug. N(sselfs_trackersircsid(sselfsircsmsgsargssid((s./Sourceforge/plugin.pysbug«ssidsbugcCs|i||ƒdS(sË Returns a description of the patch with id . Really, this is just a wrapper for the tracker command; it won't even complain if the you give isn't a patch. N(sselfs_trackersircsid(sselfsircsmsgsargssid((s./Sourceforge/plugin.pyspatchµsspatchcCs|i||ƒdS(sÈ Returns a description of the rfe with id . Really, this is just a wrapper for the tracker command; it won't even complain if the you give isn't an rfe. N(sselfs_trackersircsid(sselfsircsmsgsargssid((s./Sourceforge/plugin.pysrfe¿ssrfecCs|i||ƒdS(sk Returns a description of the tracker with id and the corresponding url. N(sselfs_trackersircsid(sselfsircsmsgsargssid((s./Sourceforge/plugin.pystrackerÉsstrackercCsŽy_d|i|f}|i|ƒ}|tjo|id|ƒn|i d||fƒWn(t j o}|it |ƒƒnXdS(Ns%s%ss Invalid Tracker page snarfed: %ss%s <%s>( sselfs _trackerURLsidsurls_getTrackerInfosrespsNonesircserrorsreplys TrackerErrorsesstr(sselfsircsidsesurlsresp((s./Sourceforge/plugin.pys_trackerÒs c Csd}x.|D]&\} } | |ijo | }q q Wy)t|ƒd|} |i | ƒdSWnt j onX| o2|i d|idƒ}| o ti‚q°ny|i|||ƒ} Wn6tj o*}|i d||iƒfƒdSnX|i|i| |ƒƒdS(Nsopens=Use the tracker command to get information about specific %s.sdefaultProjectis%s. I can't find the %s link.(sstatussoptlistsoptions_sselfs _statusOptsintsprojectstrackersssircserrors ValueErrors registryValuesmsgsargss callbackss ArgumentErrors_getTrackerURLsurls TrackerErrorses capitalizesreplys_getTrackerList( sselfsircsargssmsgsoptlistsprojectstrackersstatussesoptionsssurls_((s./Sourceforge/plugin.pys _trackersÝs,     cCs |i|||||dƒdS(sí[--{any,open,closed,deleted,pending}] [] Returns a list of the most recent bugs filed against . is not needed if there is a default project set. Search defaults to open bugs. sbugsN(sselfs _trackerssircsargssmsgsoptlistsproject(sselfsircsmsgsargssoptlistsproject((s./Sourceforge/plugin.pysbugsöss somethingcCs |i|||||dƒdS(sí[--{any,open,closed,deleted,pending}] [] Returns a list of the most recent rfes filed against . is not needed if there is a default project set. Search defaults to open rfes. srfeN(sselfs _trackerssircsargssmsgsoptlistsproject(sselfsircsmsgsargssoptlistsproject((s./Sourceforge/plugin.pysrfesscCs |i|||||dƒdS(só[--{any,open,closed,deleted,pending}] [] Returns a list of the most recent patches filed against . is not needed if there is a default project set. Search defaults to open patches. spatchesN(sselfs _trackerssircsargssmsgsoptlistsproject(sselfsircsmsgsargssoptlistsproject((s./Sourceforge/plugin.pyspatches ss(\d+)s ([\d.]+%)cs­d|}ti|ƒ} | d oˆid|ƒndfd„ƒY} ‡d†}d„}d„} yvxo| dD]c} | d } | d }d | jo| | ƒ| _qxd | jo||i| ƒ| _qxd | jo4||i| ƒ| _||i| |ƒƒ| _qxd| jo(||i| ƒ| _| |ƒ| _qxd| jo"||i| ƒ\| _| _qxd| jo"||i| ƒ\| _| _qxd| jo"||i| ƒ\| _| _qxqxWWn&tj oˆiddtƒnXˆit d| it!| iƒdf| i| it!| iƒdf| it!| iƒddf| it!| iƒddf| it!| iƒddf| iƒ ƒdS(s[] Returns the current statistics for . is not needed if there is a default project set. s;http://sourceforge.net/export/rss2_projsummary.php?project=sitemssSourceForge project namesxcBstZRS(N(s__name__s __module__(((s./Sourceforge/plugin.pysx!scsD|i|ƒ}|tj o|idƒSnˆiddtƒdS(Nis#Sourceforge gave me a bad RSS feed.sRaise( srssearchsssmsNonesgroupsircserrorsTrue(srsssm(sirc(s./Sourceforge/plugin.pysget#s cCs>g}x-|i|ƒD]}|i|idƒƒqW|SdS(Ni(sLsrsfinditersssmsappendsgroup(srsssmsL((s./Sourceforge/plugin.pysgets)s cCs|iddƒdSdS(Ns: iiÿÿÿÿ(ssssplit(ss((s./Sourceforge/plugin.pys afterColon.sstitles descriptions Project namesDevelopers on projectsActivity percentilesDownloadable filess Tracker: BugssTracker: PatchessTracker: FeaturesUnable to parse stats RSS.sRaises{%s has %n, is %s active (ranked %i), has had %n (%s today), has %n (out of %i), has %n (out of %i), and has %n (out of %i).s developersdownloadsopensbugsrfespatchN("sprojectsurls rssparsersparsesresultssircs errorInvalidsxsgetsgetss afterColonsitemstitles descriptionsselfs_intResdevss _percentResactivitysrankings downloadssdownloadsTodaysbugsOpens bugsTotals patchesOpens patchesTotalsrfesOpens rfesTotalsAttributeErrorserrorsTruesreplysformatsint(sselfsircsmsgsargssprojectsgetss descriptionsgetsurlstitlesresultssitems afterColonsx((sircs./Sourceforge/plugin.pysstatssN             " " *  sloweredsBugs\s+?\( ([^<]+)cCs…y#tiid|i|fƒ}Wn-tiij o}t it |ƒ‚nX|i i |ƒ}|o|idƒSndSdS(Ns%s%sis(sutilsswebsgetUrlsselfs _projectURLsprojectstextsErrorses callbackssstrs_totbugsssearchsmsgroup(sselfsprojectsestextsm((s./Sourceforge/plugin.pys _getNumBugsVs#s)Feature Requests\s+?\( ([^<]+)cCs…y#tiid|i|fƒ}Wn-tiij o}t it |ƒ‚nX|i i |ƒ}|o|idƒSndSdS(Ns%s%sis(sutilsswebsgetUrlsselfs _projectURLsprojectstextsErrorses callbackssstrs_totrfesssearchsmsgroup(sselfsprojectsestextsm((s./Sourceforge/plugin.pys _getNumRfescs#cCsL|djo|i|||ƒn%|djo|i|||ƒndS(s{bugs,rfes} [] Returns the total count of open bugs or rfes. is only necessary if a default project is not set. sbugssrfesN(stypesselfs _totalbugssircsmsgsprojects _totalrfes(sselfsircsmsgsargsstypesproject((s./Sourceforge/plugin.pystotalns   sliteralsbugssrfescCs\|p|id|idƒ}|i|ƒ}|o|i|ƒn|i d|ƒdS(NsdefaultProjectis%Could not find bug statistics for %s.( sprojectsselfs registryValuesmsgsargss _getNumBugsstotalsircsreplyserror(sselfsircsmsgsprojectstotal((s./Sourceforge/plugin.pys _totalbugszs  cCs\|p|id|idƒ}|i|ƒ}|o|i|ƒn|i d|ƒdS(NsdefaultProjectis%Could not find RFE statistics for %s.( sprojectsselfs registryValuesmsgsargss _getNumRfesstotalsircsreplyserror(sselfsircsmsgsprojectstotal((s./Sourceforge/plugin.pys _totalrfes‚s  cCsM|i}d}xv|D]n\}} |djo |i}n|djo |i}n|djo d}n|djo d}qqWg} xU|D]M}||ƒ} | o4| i t | idƒ|iƒdƒ|fƒq•q•W| iƒ| iƒdigi }| D]"\} } |td | | ƒƒq~ƒ} |i| ƒd S( sØ[--{bugs,rfes}] [--{open,closed}] [ ...] Returns the projects, in order, from greatest number of bugs to least. Defaults to bugs and open. isbugssrfessopensclosedis/s, s'%s': %iN(sselfs _getNumBugsssearchstypesoptlistsoptions_s _getNumRfessresultssprojectssprojsnumsappendsintssplitssortsreversesjoins_[1]sisssformatsircsreply(sselfsircsmsgsargssoptlistsprojectss_[1]ssearchsoptionsresultssisssnums_stypesproj((s./Sourceforge/plugin.pysfightŠs.          8  BcCs®|id|idƒ odSnyY|idƒ}|i|ƒ}|t jo|i i d|ƒn|i |dtƒWn+tj o}|i i t|ƒƒnXdS(sohttps?://(?:www\.)?(?:sourceforge|sf)\.net/tracker/.*\?(?:&?func=detail|&?aid=\d+|&?group_id=\d+|&?atid=\d+){4}strackerSnarferiNs Invalid Tracker page snarfed: %ss prefixNick(sselfs registryValuesmsgsargssmatchsgroupsurls_getTrackerInfosrespsNoneslogsinfosircsreplysFalses TrackerErrorsesstr(sselfsircsmsgsmatchsurlsesresp((s./Sourceforge/plugin.pys sfSnarfer¨s (4s__name__s __module__s__doc__sTruesthreadeds callBeforesregexpssresIsSs_reoptsscompiles_infoRes _hrefOptss _statusOpts_optDicts _projectURLs _trackerURLs__init__s isCommands _formatResps_getTrackerURLs_getTrackerLists_sfTitles _linkHrefs_getTrackerInfosbugswrapspatchsrfestrackers_trackers _trackerssbugssgetoptss additionalsrfesspatchess_intRes _percentResstatss_totbugss _getNumBugss_totrfess _getNumRfesstotals _totalbugss _totalrfessfightsmanys sfSnarfers urlSnarfer(((s./Sourceforge/plugin.pys Sourceforge,sj     33     -      $ $ $ =  '   E (sres rssparsers BeautifulSoups supybot.confsconfs supybot.utilssutilsssupybot.commandsssupybot.ircutilssircutilsssupybot.callbackss callbackss Exceptions TrackerErrors PluginRegexps SourceforgesClass( s callbackssutilss BeautifulSoupsres TrackerErrorsconfs rssparsers SourceforgesClasssircutils((s./Sourceforge/plugin.pys?s       ÿŽ