-
Notifications
You must be signed in to change notification settings - Fork 206
PackageRank #1091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
PackageRank #1091
Changes from all commits
40dfc83
cbbaeb6
164128b
54de869
1e2c6c8
e777bf2
6a45d62
0a6dc00
722103b
056c833
c0abd3d
4c7dba1
36ef484
53f5104
1a157b8
7ab35a9
8d5e68a
3859803
95e02d3
c145124
faa42c2
64453e8
3c93212
73a65c9
bf38c80
bf77ee3
a27a0c7
8931732
b5ca917
37ce2fb
817559d
0cd6c96
983606f
5147554
22bdc45
8acc750
6be2930
8745c69
a3bb571
e53968c
16d6e67
f90c797
d878f42
a7bcef6
6a887b5
e881d70
b2a80ce
3089b6d
b888ccb
4748abd
7609a8a
f26effe
5f38c6b
2ba5071
a3c81fa
ead8f6b
9d4d811
2cd996b
32995c8
39b28de
5d354da
fc4c527
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,10 @@ import Distribution.Server.Features.DownloadCount | |
import Distribution.Server.Features.Tags | ||
import Distribution.Server.Features.Users | ||
import Distribution.Server.Features.Upload(UploadFeature(..)) | ||
import Distribution.Server.Features.Documentation (DocumentationFeature(..)) | ||
import Distribution.Server.Features.TarIndexCache (TarIndexCacheFeature(..)) | ||
import Distribution.Server.Features.PackageList.PackageRank | ||
|
||
import Distribution.Server.Users.Users (userIdToName) | ||
import qualified Distribution.Server.Users.UserIdSet as UserIdSet | ||
import Distribution.Server.Users.Group(UserGroup(..), GroupDescription(..)) | ||
|
@@ -31,6 +35,7 @@ import Distribution.PackageDescription.Configuration | |
import Distribution.Pretty (prettyShow) | ||
import Distribution.Types.Version (Version) | ||
import Distribution.Utils.ShortText (fromShortText) | ||
import Distribution.Simple.Utils (safeLast) | ||
|
||
import Control.Concurrent | ||
import qualified Data.List.NonEmpty as NE | ||
|
@@ -41,7 +46,6 @@ import Data.Set (Set) | |
import qualified Data.Set as Set | ||
import Data.Time.Clock (UTCTime(..)) | ||
|
||
|
||
data ListFeature = ListFeature { | ||
listFeatureInterface :: HackageFeature, | ||
|
||
|
@@ -91,11 +95,13 @@ data PackageItem = PackageItem { | |
-- Hotness = recent downloads + stars + 2 * no rev deps | ||
itemHotness :: !Float, | ||
-- Reference version (non-deprecated highest numbered version) | ||
itemReferenceVersion :: !String | ||
itemReferenceVersion :: !String, | ||
-- heuristic way to sort packages | ||
itemPackageRank :: !Float | ||
} | ||
|
||
instance MemSize PackageItem where | ||
memSize (PackageItem a b c d e f g h i j k l _m n o) = memSize11 a b c d e f g h i j (k, l, n, o) | ||
memSize (PackageItem a b c d e f g h i j k l _m n o r) = memSize12 a b c d e f g h i j (k, l, n, o) r | ||
|
||
|
||
emptyPackageItem :: PackageName -> PackageItem | ||
|
@@ -115,10 +121,10 @@ emptyPackageItem pkg = | |
itemNumBenchmarks = 0, | ||
itemLastUpload = UTCTime (toEnum 0) 0, | ||
itemHotness = 0, | ||
itemReferenceVersion = "" | ||
itemReferenceVersion = "", | ||
itemPackageRank = 0 | ||
} | ||
|
||
|
||
initListFeature :: ServerEnv | ||
-> IO (CoreFeature | ||
-> ReverseFeature | ||
|
@@ -128,6 +134,8 @@ initListFeature :: ServerEnv | |
-> VersionsFeature | ||
-> UserFeature | ||
-> UploadFeature | ||
-> DocumentationFeature | ||
-> TarIndexCacheFeature | ||
-> IO ListFeature) | ||
initListFeature _env = do | ||
itemCache <- newMemStateWHNF Map.empty | ||
|
@@ -140,11 +148,12 @@ initListFeature _env = do | |
tagsf@TagsFeature{..} | ||
versions@VersionsFeature{..} | ||
users@UserFeature{..} | ||
uploads@UploadFeature{..} -> do | ||
uploads@UploadFeature{..} | ||
documentation tar -> do | ||
|
||
let (feature, modifyItem, updateDesc) = | ||
listFeature core revs download votesf tagsf versions users uploads | ||
itemCache itemUpdate | ||
itemCache itemUpdate documentation tar _env | ||
|
||
registerHookJust packageChangeHook isPackageChangeAny $ \(pkgid, _) -> | ||
updateDesc (packageName pkgid) | ||
|
@@ -213,19 +222,23 @@ listFeature :: CoreFeature | |
-> UploadFeature | ||
-> MemState (Map PackageName PackageItem) | ||
-> Hook (Set PackageName) () | ||
-> DocumentationFeature | ||
-> TarIndexCacheFeature | ||
-> ServerEnv | ||
-> (ListFeature, | ||
PackageName -> (PackageItem -> PackageItem) -> IO (), | ||
PackageName -> IO ()) | ||
|
||
listFeature CoreFeature{..} | ||
ReverseFeature{revDirectCount} | ||
ReverseFeature{revDirectCount, revPackageStats} | ||
DownloadFeature{..} | ||
VotesFeature{..} | ||
TagsFeature{..} | ||
VersionsFeature{..} | ||
versions@VersionsFeature{..} | ||
UserFeature{..} | ||
UploadFeature{..} | ||
itemCache itemUpdate | ||
documentation tar env | ||
= (ListFeature{..}, modifyItem, updateDesc) | ||
where | ||
listFeatureInterface = (emptyHackageFeature "list") { | ||
|
@@ -256,7 +269,7 @@ listFeature CoreFeature{..} | |
let pkgs = PackageIndex.lookupPackageName index pkgname | ||
case pkgs of | ||
[] -> return () --this shouldn't happen | ||
_ -> modifyMemState itemCache . uncurry Map.insert =<< constructItem (last pkgs) | ||
_ -> modifyMemState itemCache . uncurry Map.insert =<< constructItem pkgs | ||
|
||
updateDesc pkgname = do | ||
index <- queryGetPackageIndex | ||
|
@@ -277,21 +290,25 @@ listFeature CoreFeature{..} | |
constructItemIndex :: IO (Map PackageName PackageItem) | ||
constructItemIndex = do | ||
index <- queryGetPackageIndex | ||
items <- mapM (constructItem . last) $ PackageIndex.allPackagesByName index | ||
items <- mapM constructItem $ PackageIndex.allPackagesByName index | ||
return $ Map.fromList items | ||
|
||
constructItem :: PkgInfo -> IO (PackageName, PackageItem) | ||
constructItem pkg = do | ||
constructItem :: [PkgInfo] -> IO (PackageName, PackageItem) | ||
constructItem pkgs = do | ||
let pkgname = packageName pkg | ||
desc = pkgDesc pkg | ||
intRevDirectCount <- revDirectCount pkgname | ||
pkg = last pkgs | ||
-- [reverse index disabled] revCount <- query . GetReverseCount $ pkgname | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line was removed in 4d0bd17, and it doesn't seem related to the PackageRank feature. A merge was probably botched. I'd recommend rebasing and squashing, make sure every hunk is related to PackageRank. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, It indeed was a botched merge, which I now tried to fix by rebasing but probably forgot this, I will get to it. |
||
revCount@(ReverseCount intRevDirectCount _) <- revPackageStats pkgname | ||
users <- queryGetUserDb | ||
tags <- queryTagsForPackage pkgname | ||
downs <- recentPackageDownloads | ||
votes <- pkgNumScore pkgname | ||
deprs <- queryGetDeprecatedFor pkgname | ||
maintainers <- queryUserGroup (maintainersGroup pkgname) | ||
prefsinfo <- queryGetPreferredInfo pkgname | ||
packageR <- rankPackage versions (cmFind pkgname downs) (UserIdSet.size maintainers) | ||
documentation tar env pkgs (safeLast pkgs) revCount | ||
|
||
return $ (,) pkgname . updateReferenceVersion prefsinfo [pkgVersion (pkgInfoId pkg)] $ (updateDescriptionItem desc $ emptyPackageItem pkgname) { | ||
itemTags = tags | ||
|
@@ -302,6 +319,7 @@ listFeature CoreFeature{..} | |
, itemLastUpload = fst (pkgOriginalUploadInfo pkg) | ||
, itemRevDepsCount = intRevDirectCount | ||
, itemHotness = votes + fromIntegral (cmFind pkgname downs) + fromIntegral intRevDirectCount * 2 | ||
, itemPackageRank = packageR | ||
} | ||
|
||
------------------------------ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
{-# LANGUAGE ScopedTypeVariables, FlexibleInstances, MultiParamTypeClasses, ConstraintKinds #-} | ||
module Distribution.Server.Features.PackageList.MStats | ||
( parseM | ||
, sumMStat | ||
, getListsTables | ||
, getCode | ||
, getHCode | ||
, getSections | ||
, MStats(..) | ||
) where | ||
|
||
import Commonmark | ||
import Commonmark.Extensions | ||
import Control.Monad.Identity | ||
import qualified Data.ByteString.Lazy as BS | ||
( ByteString | ||
, toStrict ) | ||
import qualified Data.Text as T | ||
import qualified Data.Text.Encoding as T | ||
import qualified Data.Text.Encoding.Error as T | ||
( lenientDecode ) | ||
|
||
-- parses markdown into statistics needed for readmeScore | ||
parseM :: BS.ByteString -> FilePath -> Either ParseError [MarkdownStats] | ||
parseM md name = runIdentity | ||
(commonmarkWith (pipeTableSpec <> defaultSyntaxSpec) name txt) | ||
where txt = T.decodeUtf8With T.lenientDecode . BS.toStrict $ md | ||
|
||
data MarkdownStats = NotImportant MStats | | ||
HCode MStats | | ||
Code MStats | | ||
Section MStats | | ||
Table Int MStats | -- Int of rows | ||
PText MStats | | ||
List Int MStats -- Int of elements | ||
deriving (Show) | ||
|
||
data MStats = MStats Int Int --number of pictures, number of chars | ||
deriving Show | ||
|
||
instance Monoid MStats where | ||
mempty = MStats 0 0 | ||
|
||
instance Rangeable MStats where | ||
ranged = const id | ||
|
||
instance HasAttributes MStats where | ||
addAttributes = const id | ||
|
||
instance Semigroup MStats where | ||
(MStats a b) <> (MStats c d) = MStats (a + c) (b + d) | ||
|
||
-- Getter functions | ||
|
||
getCode :: [MarkdownStats] -> (Int, Int) -- number of code blocks, size of code | ||
getCode [] = (0, 0) | ||
getCode (Code (MStats codeT _) : xs) = (1, codeT) >< getCode xs | ||
getCode (HCode (MStats codeT _) : xs) = (1, codeT) >< getCode xs | ||
getCode (_ : xs) = getCode xs | ||
|
||
getHCode :: [MarkdownStats] -> (Int, Int) -- number of code blocks, size of code | ||
getHCode [] = (0, 0) | ||
getHCode (HCode (MStats codeT _) : xs) = (1, codeT) >< getHCode xs | ||
getHCode (_ : xs) = getHCode xs | ||
|
||
getSections :: [MarkdownStats] -> Int -- number of code blocks, size of code | ||
getSections [] = 0 | ||
getSections (Section _ : xs) = 1 + getSections xs | ||
getSections (_ : xs) = getSections xs | ||
|
||
sumMStat :: [MarkdownStats] -> MStats | ||
sumMStat [] = mempty | ||
sumMStat (x : xs) = case x of | ||
(NotImportant a) -> a <> sumMStat xs | ||
(Section a) -> a <> sumMStat xs | ||
(List _ a ) -> a <> sumMStat xs | ||
(Table _ a ) -> a <> sumMStat xs | ||
(HCode a ) -> a <> sumMStat xs | ||
(Code a ) -> a <> sumMStat xs | ||
(PText a ) -> a <> sumMStat xs | ||
|
||
getListsTables :: [MarkdownStats] -> Int | ||
getListsTables [] = 0 | ||
getListsTables ((List a _) : ys) = a + getListsTables ys | ||
getListsTables ((Table a _) : ys) = a + getListsTables ys | ||
getListsTables (_ : ys) = getListsTables ys | ||
|
||
-- helper | ||
(><) :: (Int, Int) -> (Int, Int) -> (Int, Int) | ||
(><) (a, b) (c, d) = (a + c, b + d) | ||
|
||
-- INSTANCES | ||
instance Rangeable [MarkdownStats] where | ||
ranged = const id | ||
|
||
instance HasAttributes [MarkdownStats] where | ||
addAttributes = const id | ||
|
||
instance HasPipeTable MStats [MarkdownStats] where | ||
pipeTable _ _ rows = [Table (length rows) (mconcat $ mconcat <$> rows)] | ||
|
||
instance IsInline MStats where | ||
lineBreak = MStats 0 1 | ||
softBreak = MStats 0 1 | ||
str t = MStats 0 (T.length t) | ||
entity t = MStats 0 (T.length t) | ||
escapedChar _ = MStats 0 1 | ||
emph = id | ||
strong = id | ||
link _ _ a = a | ||
image _ _ (MStats a b) = MStats (a + 1) b | ||
code t = MStats 0 (T.length t) | ||
rawInline _ t = MStats 0 (T.length t) | ||
|
||
instance IsBlock MStats [MarkdownStats] where | ||
paragraph a = [PText a] | ||
plain a = [PText a] | ||
thematicBreak = [NotImportant mempty] | ||
blockQuote = id | ||
codeBlock language codeT | language == T.pack "haskell" = [HCode (code codeT)] | ||
| otherwise = [Code (code codeT)] | ||
heading _ a = [Section a] | ||
rawBlock _ _ = [NotImportant mempty] | ||
referenceLinkDefinition _ _ = [NotImportant mempty] | ||
list _ _ l = [List (length l + sumLT l) (mconcat $ sumMStat <$> l)] | ||
where sumLT a = sum (getListsTables <$> a) |
Uh oh!
There was an error while loading. Please reload this page.