@@ -70,15 +70,12 @@ import Data.Array (Array, listArray)
70
70
import qualified Data.Array as Array
71
71
import qualified Data.Ix as Ix
72
72
import Data.Time.Format (formatTime )
73
- import Data.Time.Clock (getCurrentTime )
74
- import qualified Data.Time.Format.Human as HumanTime
75
73
import Data.Time.Locale.Compat (defaultTimeLocale )
76
74
import qualified Data.ByteString.Lazy as BS (ByteString )
77
75
78
76
import Text.XHtml.Strict
79
77
import qualified Text.XHtml.Strict as XHtml
80
78
import Text.XHtml.Table (simpleTable )
81
- import Network.URI (escapeURIString , isUnreserved )
82
79
83
80
84
81
-- TODO: move more of the below to Distribution.Server.Pages.*, it's getting
@@ -129,6 +126,7 @@ initHtmlFeature env@ServerEnv{serverTemplatesDir, serverTemplatesMode,
129
126
, " distro-monitor.html"
130
127
, " revisions.html"
131
128
, " package-page.html"
129
+ , " table-interface.html"
132
130
]
133
131
134
132
@@ -158,7 +156,7 @@ initHtmlFeature env@ServerEnv{serverTemplatesDir, serverTemplatesMode,
158
156
tarIndexCache
159
157
reportsCore
160
158
usersdetails
161
- (htmlUtilities core tags)
159
+ (htmlUtilities core tags user )
162
160
mainCache namesCache
163
161
templates
164
162
@@ -268,6 +266,8 @@ htmlFeature env@ServerEnv{..}
268
266
cachePackagesPage
269
267
cacheNamesPage
270
268
templates
269
+ list
270
+ names
271
271
htmlUsers = mkHtmlUsers user usersdetails
272
272
htmlUploads = mkHtmlUploads utilities upload
273
273
htmlDocUploads = mkHtmlDocUploads utilities core docsCore templates
@@ -277,8 +277,8 @@ htmlFeature env@ServerEnv{..}
277
277
docsCandidates tarIndexCache
278
278
candidates templates
279
279
htmlPreferred = mkHtmlPreferred utilities core versions
280
- htmlTags = mkHtmlTags utilities core list tags
281
- htmlSearch = mkHtmlSearch utilities core list names
280
+ htmlTags = mkHtmlTags utilities core list tags templates
281
+ htmlSearch = mkHtmlSearch utilities core list names templates
282
282
283
283
htmlResources = concat [
284
284
htmlCoreResources htmlCore
@@ -460,11 +460,13 @@ mkHtmlCore :: ServerEnv
460
460
-> AsyncCache Response
461
461
-> AsyncCache Response
462
462
-> Templates
463
+ -> ListFeature
464
+ -> SearchFeature
463
465
-> HtmlCore
464
466
mkHtmlCore ServerEnv {serverBaseURI}
465
467
utilities@ HtmlUtilities {.. }
466
468
UserFeature {queryGetUserDb, checkAuthenticated}
467
- CoreFeature {coreResource}
469
+ CoreFeature {coreResource, queryGetPackageIndex }
468
470
VersionsFeature { versionsResource
469
471
, queryGetDeprecatedFor
470
472
, queryGetPreferredInfo
@@ -484,6 +486,8 @@ mkHtmlCore ServerEnv{serverBaseURI}
484
486
cachePackagesPage
485
487
cacheNamesPage
486
488
templates
489
+ ListFeature {makeItemList}
490
+ SearchFeature {.. }
487
491
= HtmlCore {.. }
488
492
where
489
493
cores@ CoreResource {packageInPath, lookupPackageName, lookupPackageId} = coreResource
@@ -511,6 +515,10 @@ mkHtmlCore ServerEnv{serverBaseURI}
511
515
, (resourceAt " /packages/names" ) {
512
516
resourceGet = [(" html" , const $ readAsyncCache cacheNamesPage)]
513
517
}
518
+ , (resourceAt " /packages/browse" ) {
519
+ resourceDesc = [(GET , " Show browsable list of all packages" )]
520
+ , resourceGet = [(" html" , serveBrowsePage)]
521
+ }
514
522
, (extendResource $ corePackagesPage cores) {
515
523
resourceDesc = [(GET , " Show package index" )]
516
524
, resourceGet = [(" html" , const $ readAsyncCache cachePackagesPage)]
@@ -608,6 +616,21 @@ mkHtmlCore ServerEnv{serverBaseURI}
608
616
, " versions" $= map packageId pkgs
609
617
]
610
618
619
+ serveBrowsePage :: DynamicPath -> ServerPartE Response
620
+ serveBrowsePage _ = do
621
+ pkgIndex <- queryGetPackageIndex
622
+ let packageNames = Pages. toPackageNames pkgIndex
623
+ pkgDetails <- liftIO $ makeItemList packageNames
624
+ let rowList = map makeRow pkgDetails
625
+ tabledata = " " +++ rowList +++ " "
626
+ cacheControl [Public , maxAgeHours 1 ]
627
+ (etagFromHash (PackageIndex. indexSize pkgIndex))
628
+ template <- getTemplate templates " table-interface.html"
629
+ return $ toResponse $ template
630
+ [ " heading" $= " All packages"
631
+ , " content" $= " A browsable index of all the packages"
632
+ , " tabledata" $= tabledata ]
633
+
611
634
serveDistroMonitorPage :: DynamicPath -> ServerPartE Response
612
635
serveDistroMonitorPage dpath = do
613
636
pkgname <- packageInPath dpath
@@ -1446,6 +1469,7 @@ mkHtmlTags :: HtmlUtilities
1446
1469
-> CoreFeature
1447
1470
-> ListFeature
1448
1471
-> TagsFeature
1472
+ -> Templates
1449
1473
-> HtmlTags
1450
1474
mkHtmlTags HtmlUtilities {.. }
1451
1475
CoreFeature { coreResource = CoreResource {
@@ -1454,7 +1478,9 @@ mkHtmlTags HtmlUtilities{..}
1454
1478
}
1455
1479
}
1456
1480
ListFeature {makeItemList}
1457
- TagsFeature {.. } = HtmlTags {.. }
1481
+ TagsFeature {.. }
1482
+ templates
1483
+ = HtmlTags {.. }
1458
1484
where
1459
1485
tags = tagsResource
1460
1486
@@ -1500,17 +1526,21 @@ mkHtmlTags HtmlUtilities{..}
1500
1526
pkgs = Set. toList pkgnames
1501
1527
items <- liftIO $ makeItemList pkgs
1502
1528
let (mtag, histogram) = Map. updateLookupWithKey (\ _ _ -> Nothing ) tg $ tagHistogram items
1529
+ rowList = map makeRow items
1503
1530
-- make a 'related tags' section, so exclude this tag from the histogram
1504
1531
count = fromMaybe 0 mtag
1505
- return $ toResponse $ Resource. XHtml $ hackagePage tagd $
1506
- [ h2 << tagd
1507
- , case items of
1532
+ template <- getTemplate templates " table-interface.html"
1533
+ return $ toResponse $ template
1534
+ [ " heading" $= tagd
1535
+ , " content" $= case items of
1508
1536
[] -> toHtml " No packages have this tag."
1509
1537
_ -> toHtml
1510
1538
[ paragraph << [if count== 1 then " 1 package has" else show count ++ " packages have" , " this tag." ]
1511
1539
, paragraph ! [theclass " toc" ] << [toHtml " Related tags: " , toHtml $ showHistogram histogram]
1512
- , ulist ! [theclass " packages" ] << map renderItem items ]
1540
+ ]
1541
+ , " tabledata" $= rowList
1513
1542
]
1543
+
1514
1544
where
1515
1545
showHistogram hist = (++ takeHtml) . intersperse (toHtml " , " ) $
1516
1546
map histogramEntry $ take takeAmount sortHist
@@ -1554,11 +1584,13 @@ mkHtmlSearch :: HtmlUtilities
1554
1584
-> CoreFeature
1555
1585
-> ListFeature
1556
1586
-> SearchFeature
1587
+ -> Templates
1557
1588
-> HtmlSearch
1558
1589
mkHtmlSearch HtmlUtilities {.. }
1559
1590
CoreFeature {.. }
1560
1591
ListFeature {makeItemList}
1561
- SearchFeature {.. } =
1592
+ SearchFeature {.. }
1593
+ templates =
1562
1594
HtmlSearch {.. }
1563
1595
where
1564
1596
htmlSearchResources = [
@@ -1569,10 +1601,10 @@ mkHtmlSearch HtmlUtilities{..}
1569
1601
1570
1602
servePackageFind :: DynamicPath -> ServerPartE Response
1571
1603
servePackageFind _ = do
1572
- (mtermsStr, offset, limit, mexplain) <-
1573
- queryString $ (,,, ) <$> optional (look " terms" )
1574
- <*> mplus (lookRead " offset" ) (pure 0 )
1575
- <*> mplus (lookRead " limit" ) (pure 100 )
1604
+ (mtermsStr, mexplain) <-
1605
+ queryString $ (,) <$> optional (look " terms" )
1606
+ -- <*> mplus (lookRead "offset") (pure 0)
1607
+ -- <*> mplus (lookRead "limit") (pure 100)
1576
1608
<*> optional (look " explain" )
1577
1609
let explain = isJust mexplain
1578
1610
case mtermsStr of
@@ -1587,18 +1619,23 @@ mkHtmlSearch HtmlUtilities{..}
1587
1619
, toHtml $ explainResults results
1588
1620
]
1589
1621
1590
- Just termsStr | terms <- words termsStr, not (null terms) -> do
1591
- pkgIndex <- liftIO $ queryGetPackageIndex
1592
- currentTime <- liftIO $ getCurrentTime
1593
- pkgnames <- searchPackages terms
1594
- let (pageResults, moreResults) = splitAt limit (drop offset pkgnames)
1595
- pkgDetails <- liftIO $ makeItemList pageResults
1596
- return $ toResponse $ Resource. XHtml $
1597
- hackagePage " Package search" $
1598
- [ toHtml $ searchForm termsStr False
1599
- , toHtml $ resultsArea pkgIndex currentTime pkgDetails offset limit moreResults termsStr
1600
- , alternativeSearchTerms termsStr
1601
- ]
1622
+ Just termsStr | terms <- words termsStr -> do
1623
+ -- pkgIndex <- liftIO $ queryGetPackageIndex
1624
+ -- currentTime <- liftIO $ getCurrentTime
1625
+ pkgnames <- if null terms
1626
+ then fmap Pages. toPackageNames queryGetPackageIndex
1627
+ else searchPackages terms
1628
+ -- let (pageResults, moreResults) = splitAt limit (drop offset pkgnames)
1629
+ pkgDetails <- liftIO $ makeItemList pkgnames
1630
+
1631
+ let rowList = map makeRow pkgDetails
1632
+ tabledata = " " +++ rowList
1633
+ template <- getTemplate templates " table-interface.html"
1634
+ return $ toResponse $ template
1635
+ [ " heading" $= toHtml (searchForm termsStr False )
1636
+ , " content" $= " A browsable index of all the packages"
1637
+ , " tabledata" $= tabledata
1638
+ , " footer" $= alternativeSearchTerms termsStr]
1602
1639
1603
1640
_ ->
1604
1641
return $ toResponse $ Resource. XHtml $
@@ -1607,55 +1644,6 @@ mkHtmlSearch HtmlUtilities{..}
1607
1644
, alternativeSearch
1608
1645
]
1609
1646
where
1610
- resultsArea pkgIndex currentTime pkgDetails offset limit moreResults termsStr =
1611
- [ h2 << " Results"
1612
- , if offset == 0
1613
- then noHtml
1614
- else paragraph << (" (" ++ show (fst range + 1 ) ++ " to "
1615
- ++ show (snd range) ++ " )" )
1616
- , case pkgDetails of
1617
- [] | offset == 0 -> toHtml " None"
1618
- | otherwise -> toHtml " No more results"
1619
- _ -> toHtml
1620
- [ ulist ! [theclass " searchresults" ]
1621
- << map renderSearchResult pkgDetails
1622
- , if null moreResults
1623
- then noHtml
1624
- else anchor ! [href moreResultsLink]
1625
- << " More results..."
1626
- ]
1627
- ]
1628
- where
1629
- renderSearchResult :: PackageItem -> Html
1630
- renderSearchResult item = li ! classes <<
1631
- [ packageNameLink pkgname
1632
- , toHtml $ " " ++ ptype
1633
- , br
1634
- , toHtml (itemDesc item)
1635
- , br
1636
- , small ! [ theclass " info" ] <<
1637
- [ toHtml (renderTags (itemTags item))
1638
- , " Last uploaded " +++ humanTime ]
1639
- ]
1640
- where
1641
- pkgname = itemName item
1642
- timestamp = maximum
1643
- $ map pkgOriginalUploadTime
1644
- $ PackageIndex. lookupPackageName pkgIndex pkgname
1645
- -- takes current time as argument so it can say how many $X ago something was
1646
- humanTime = HumanTime. humanReadableTime' currentTime timestamp
1647
- ptype = packageType (itemHasLibrary item) (itemNumExecutables item)
1648
- (itemNumTests item) (itemNumBenchmarks item)
1649
- classes = case classList of [] -> [] ; _ -> [theclass $ unwords classList]
1650
- classList = (case itemDeprecated item of Nothing -> [] ; _ -> [" deprecated" ])
1651
-
1652
- range = (offset, offset + length pkgDetails)
1653
- moreResultsLink =
1654
- " /packages/search?"
1655
- ++ " terms=" ++ escapeURIString isUnreserved termsStr
1656
- ++ " &offset=" ++ show (offset + limit)
1657
- ++ " &limit=" ++ show limit
1658
-
1659
1647
searchForm termsStr explain =
1660
1648
[ h2 << " Package search"
1661
1649
, form ! [XHtml. method " GET" , action " /packages/search" ] <<
0 commit comments