@@ -6,8 +6,9 @@ module Distribution.Server.Features.PackageRank
66 ( rankPackage
77 ) where
88
9- import Distribution.Server.Features.PackageRank.Parser
9+ import Distribution.Server.Features.PackageRank.Parser
1010
11+ import Data.TarIndex ( TarEntryOffset )
1112import Distribution.Package
1213import Distribution.PackageDescription
1314import Distribution.Server.Features.Documentation
@@ -17,9 +18,14 @@ import Distribution.Server.Features.PreferredVersions.State
1718import Distribution.Server.Features.TarIndexCache
1819import qualified Distribution.Server.Framework.BlobStorage
1920 as BlobStorage
21+ import Distribution.Server.Framework.CacheControl
2022import Distribution.Server.Framework.ServerEnv
2123 ( ServerEnv (.. ) )
2224import Distribution.Server.Packages.Types
25+ import Distribution.Server.Util.Markdown
26+ ( supposedToBeMarkdown )
27+ import Distribution.Server.Util.ServeTarball
28+ ( loadTarEntry )
2329import Distribution.Simple.Utils ( safeHead
2430 , safeLast
2531 )
@@ -38,8 +44,6 @@ import Distribution.Server.Packages.Readme
3844import GHC.Float ( int2Float )
3945import System.FilePath ( isExtensionOf )
4046
41- -- import Debug.Trace (trace)
42-
4347data Scorer = Scorer
4448 { maximumS :: ! Float
4549 , score :: ! Float
@@ -54,7 +58,7 @@ scorer maxim scr =
5458 if maxim >= scr then Scorer maxim scr else Scorer maxim maxim
5559
5660fracScor :: Float -> Float -> Scorer
57- fracScor maxim frac = scorer maxim (maxim * frac)
61+ fracScor maxim frac = scorer maxim (min ( maxim * frac) maxim )
5862
5963boolScor :: Float -> Bool -> Scorer
6064boolScor k True = Scorer k k
@@ -102,10 +106,9 @@ freshness (x : xs) lastUpd app =
102106 age = flip numDays (Just lastUpd) . Just <$> CL. getCurrentTime
103107 decayDays = expectedUpdateInterval / 2 + (if app then 300 else 200 )
104108
105- cabalScore :: PackageDescription -> IO Bool -> IO Scorer
109+ cabalScore :: PackageDescription -> Bool -> Scorer
106110cabalScore p docum =
107- (<>) (tests <> benchs <> desc <> homeP <> sourceRp <> cats)
108- <$> (boolScor 30 <$> docum)
111+ tests <> benchs <> desc <> homeP <> sourceRp <> cats <> boolScor 30 docum
109112 where
110113 tests = boolScor 50 (hasTests p)
111114 benchs = boolScor 10 (hasBenchmarks p)
@@ -115,9 +118,38 @@ cabalScore p docum =
115118 sourceRp = boolScor 8 (not $ null $ sourceRepos p)
116119 cats = boolScor 5 (not $ S. null $ category p)
117120
118- readmeScore _ = Scorer 0 0
121+ readmeScore
122+ :: Maybe (FilePath , ETag , Data.TarIndex. TarEntryOffset , FilePath )
123+ -> Bool
124+ -> IO Scorer
125+ readmeScore Nothing _ = return $ Scorer 1 0 -- readmeScore is scaled so it does not need correct max
126+ readmeScore (Just (tarfile, _, offset, name)) app = do
127+ entr <- loadTarEntry tarfile offset
128+ case entr of
129+ (Right (size, str)) -> return $ calcScore str size name
130+ _ -> return $ Scorer 1 0
131+ where
132+ calcScore str size filename =
133+ scorer 75 (min 1 (fromInteger (toInteger size) / 3000 ))
134+ <> if supposedToBeMarkdown filename
135+ then case parseM str filename of
136+ Left _ -> Scorer 0 0
137+ Right mdStats -> format mdStats
138+ else Scorer 0 0
139+ format stats =
140+ fracScor (if app then 25 else 100 ) (min 1 $ int2Float hlength / 2000 )
141+ <> scorer (if app then 15 else 27 ) (int2Float blocks * 3 )
142+ <> boolScor (if app then 10 else 30 ) (clength > 150 )
143+ <> scorer 35 (int2Float images * 10 )
144+ <> scorer 30 (int2Float sections * 4 )
145+ <> scorer 25 (int2Float rows * 2 )
146+ where
147+ (blocks, clength) = getCode stats
148+ (_ , hlength) = getHCode stats
149+ MStats _ images = sumMStat stats
150+ rows = getListsTables stats
151+ sections = getSections stats
119152
120- -- queryHasDocumentation
121153baseScore
122154 :: VersionsFeature
123155 -> Int
@@ -130,18 +162,25 @@ baseScore
130162 -> IO Scorer
131163
132164baseScore vers maintainers docs env tarCache versionList lastUploads pkgI = do
133- versS <- versionScore versionList vers lastUploads pkg
134- codeS <- codeScore documSize srcLines
135- cabalS <- cabalScore pkg documHas
165+
166+ readM <- readme
167+ hasDocum <- documHas
168+ documS <- documSize
169+ srcL <- srcLines
170+
171+ versS <- versionScore versionList vers lastUploads pkg
172+ readmeS <- readmeScore readM isApp
173+
136174 return
137175 $ scale 5 versS
138- <> scale 2 codeS
176+ <> scale 2 (codeScore documS srcL)
139177 <> scale 3 (authorScore maintainers pkg)
140- <> scale 2 cabalS
141- <> scale 5 (readmeScore readme)
178+ <> scale 2 (cabalScore pkg hasDocum)
179+ <> scale 5 readmeS
142180 where
143181 pkg = packageDescription $ pkgDesc pkgI
144182 pkgId = package pkg
183+ isApp = (isNothing . library) pkg && (not . null . executables) pkg
145184 srcLines = do
146185 Right (path, _, _) <- packageTarball tarCache pkgI
147186 filterLines (isExtensionOf " .hs" ) countLines
@@ -165,6 +204,7 @@ baseScore vers maintainers docs env tarCache versionList lastUploads pkgI = do
165204 ! lns = case Tar. entryContent entry of
166205 (Tar. NormalFile str _) -> l + (int2Float . length $ BSL. split 10 str)
167206 _ -> l
207+ -- TODO might need to decode/add the other separator
168208 countSize :: (FilePath -> Bool ) -> Tar. Entry -> Float -> Float
169209 countSize f entry l = if not . f . Tar. entryPath $ entry then l else s
170210 where
@@ -185,15 +225,12 @@ authorScore maintainers desc =
185225 where
186226 maintScore = boolScor 3 (maintainers > 1 ) <> scorer 5 (int2Float maintainers)
187227
188- codeScore :: IO Float -> IO Float -> IO Scorer
189- codeScore documentS haskellL = do
190- docum <- documentS
191- haskell <- haskellL
192- return
193- $ boolScor 1 (haskell > 700 )
194- <> boolScor 1 (haskell < 80000 )
195- <> fracScor 2 (min 1 (haskell / 5000 ))
196- <> fracScor 2 (min 1 docum / ((3000 + haskell) * 200 ))
228+ codeScore :: Float -> Float -> Scorer
229+ codeScore documentS haskellL =
230+ boolScor 1 (haskellL > 700 )
231+ <> boolScor 1 (haskellL < 80000 )
232+ <> fracScor 2 (min 1 (haskellL / 5000 ))
233+ <> fracScor 2 (min 1 documentS / ((3000 + haskellL) * 200 ))
197234
198235versionScore
199236 :: [Version ]
0 commit comments