1- {-# LANGUAGE BangPatterns #-}
2-
3- -- TODO change the module name probably Distribution.Server.Features.PackageList.PackageRank
4-
1+ {-# LANGUAGE BangPatterns, ScopedTypeVariables #-}
52module Distribution.Server.Features.PackageList.PackageRank
63 ( rankPackage
74 ) where
85
9- import Distribution.Server.Features.PackageList.MStats
10-
11- import Data.TarIndex ( TarEntryOffset )
126import Distribution.Package
137import Distribution.PackageDescription
148import Distribution.Server.Features.Documentation
159 ( DocumentationFeature (.. ) )
10+ import Distribution.Server.Features.PackageList.MStats
1611import Distribution.Server.Features.PreferredVersions
1712import Distribution.Server.Features.PreferredVersions.State
1813import Distribution.Server.Features.TarIndexCache
1914import qualified Distribution.Server.Framework.BlobStorage
2015 as BlobStorage
21- import Distribution.Server.Framework.CacheControl
2216import Distribution.Server.Framework.ServerEnv
2317 ( ServerEnv (.. ) )
2418import Distribution.Server.Packages.Types
@@ -33,6 +27,9 @@ import Distribution.Types.Version
3327import qualified Distribution.Utils.ShortText as S
3428
3529import qualified Codec.Archive.Tar as Tar
30+ import Control.Exception ( SomeException (.. )
31+ , handle
32+ )
3633import qualified Data.ByteString.Lazy as BSL
3734import Data.List ( maximumBy
3835 , sortBy
@@ -44,6 +41,9 @@ import Distribution.Server.Packages.Readme
4441import GHC.Float ( int2Float )
4542import System.FilePath ( isExtensionOf )
4643
44+ handleConst :: a -> IO a -> IO a
45+ handleConst c = handle (\ (_ :: SomeException ) -> return c)
46+
4747data Scorer = Scorer
4848 { maximumS :: ! Float
4949 , score :: ! Float
@@ -117,17 +117,16 @@ cabalScore p docum =
117117 sourceRp = boolScor 8 (not $ null $ sourceRepos p)
118118 cats = boolScor 5 (not $ S. null $ category p)
119119
120- readmeScore
121- :: Maybe (FilePath , ETag , Data.TarIndex. TarEntryOffset , FilePath )
122- -> Bool
123- -> IO Scorer
124- readmeScore Nothing _ = return $ Scorer 1 0 -- readmeScore is scaled so it does not need correct max
125- readmeScore (Just (tarfile, _, offset, name)) app = do
126- entr <- loadTarEntry tarfile offset
120+ readmeScore :: TarIndexCacheFeature -> PkgInfo -> Bool -> IO Scorer
121+ readmeScore tarCache pkgI app = do
122+ Just (tarfile, _, offset, name) <- readme
123+ entr <- loadTarEntry tarfile offset
127124 case entr of
128125 (Right (size, str)) -> return $ calcScore str size name
129126 _ -> return $ Scorer 1 0
130127 where
128+ readme = findToplevelFile tarCache pkgI isReadmeFile
129+ >>= either (\ _ -> return Nothing ) (return . Just )
131130 calcScore str size filename =
132131 scorer 75 (min 1 (fromInteger (toInteger size) / 3000 ))
133132 <> if supposedToBeMarkdown filename
@@ -162,13 +161,13 @@ baseScore
162161
163162baseScore vers maintainers docs env tarCache versionList lastUploads pkgI = do
164163
165- readM <- readme
166- hasDocum <- documHas
167- documS <- documSize
168- srcL <- srcLines
164+ hasDocum <- handleConst False documHas -- Probably redundant
165+ documS <- handleConst 0 documSize
166+ srcL <- handleConst 0 srcLines
169167
170- versS <- versionScore versionList vers lastUploads pkg
171- readmeS <- readmeScore readM isApp
168+ versS <- handleConst (Scorer 1 0 )
169+ (versionScore versionList vers lastUploads pkg)
170+ readmeS <- handleConst (Scorer 1 0 ) (readmeScore tarCache pkgI isApp)
172171 return
173172 $ scale 5 versS
174173 <> scale 2 (codeScore documS srcL)
@@ -192,9 +191,6 @@ baseScore vers maintainers docs env tarCache versionList lastUploads pkgI = do
192191 filterLines (isExtensionOf " .html" ) countSize
193192 . Tar. read
194193 <$> BSL. readFile pth
195- readme = findToplevelFile tarCache pkgI isReadmeFile
196- >>= either (\ _ -> return Nothing ) (return . Just )
197-
198194 filterLines f g = Tar. foldEntries (g f) 0 (const 0 )
199195 countLines :: (FilePath -> Bool ) -> Tar. Entry -> Float -> Float
200196 countLines f entry l = if not . f . Tar. entryPath $ entry then l else lns
@@ -279,15 +275,16 @@ temporalScore p lastUploads versionList recentDownloads = do
279275 where
280276 isApp = (isNothing . library) p && (not . null . executables) p
281277 downloadScore = calcDownScore recentDownloads
282- calcDownScore i = fracScor 5
278+ calcDownScore i = fracScor
279+ 5
283280 ( (logBase 2 (int2Float $ max 0 (i - 32 ) + 32 ) - 5 )
284281 / (if isApp then 6 else 8 )
285282 )
286283 packageFreshness = case safeHead lastUploads of
287284 Nothing -> return 0
288- (Just l) -> freshness versionList l isApp
285+ (Just l) -> freshness versionList l isApp -- Getting time hopefully does not throw Exc.
289286 freshnessScore = fracScor 10 <$> packageFreshness
290- -- Missing dependencyFreshnessScore for reasonable effectivity needs caching
287+ -- Missing dependencyFreshnessScore for reasonable effectivity needs caching
291288 tractionScore = do
292289 fresh <- packageFreshness
293290 return $ boolScor 1 (fresh * int2Float recentDownloads > 200 )
@@ -315,7 +312,7 @@ rankPackage versions recentDownloads maintainers docs tarCache env pkgs (Just pk
315312 versionList
316313 uploads
317314 pkgUsed
318- depr <- deprP
315+ depr <- handleConst Nothing deprP
319316 return $ sAverage t b * case depr of
320317 Nothing -> 1
321318 _ -> 0.2
0 commit comments