tkyprof 0.0.4 → 0.0.5.1
raw patch · 21 files changed
+296/−137 lines, 21 filesbinary-added
Files
- Controller.hs +1/−1
- Handler/Home.hs +5/−1
- Handler/Reports.hs +4/−30
- Handler/Reports/Helpers.hs +47/−0
- Model.hs +3/−3
- TKYProf.hs +1/−0
- bin/tkyprof.hs +7/−7
- config/favicon.ico binary
- config/favicon.png binary
- config/routes +1/−1
- hamlet/default-layout.hamlet +3/−6
- hamlet/header.hamlet +13/−0
- hamlet/home.hamlet +15/−8
- hamlet/reports-id.hamlet +21/−40
- hamlet/reports.hamlet +9/−6
- lucius/default-layout.lucius +35/−5
- lucius/header.lucius +32/−0
- lucius/home.lucius +15/−8
- lucius/reports-id.lucius +78/−17
- static/images/tkyprof-logo-orange.png binary
- tkyprof.cabal +6/−4
Controller.hs view
@@ -23,7 +23,7 @@ -- Some default handlers that ship with the Yesod site template. You will -- very rarely need to modify this. getFaviconR :: Handler ()-getFaviconR = sendFile "image/x-icon" "config/favicon.ico"+getFaviconR = sendFile "image/png" "config/favicon.png" getRobotsR :: Handler RepPlain getRobotsR = return $ RepPlain $ toContent ("User-agent: *" :: ByteString)
Handler/Home.hs view
@@ -2,6 +2,9 @@ module Handler.Home where import TKYProf import Yesod.Form (Enctype(Multipart))+import Data.Maybe (listToMaybe)+import Handler.Reports.Helpers (getAllReports)+import ProfilingReport (ProfilingReport(..)) -- This is a handler function for the GET request method on the RootR -- resource pattern. All of your resource patterns are defined in@@ -12,8 +15,9 @@ -- inclined, or create a single monolithic file. getHomeR :: Handler RepHtml getHomeR = do+ reports <- getAllReports defaultLayout $ do- setTitle "Devel.TKYProf Home"+ setTitle "TKYProf" addScript $ StaticR js_jquery_ui_widget_js addScript $ StaticR js_jquery_iframe_transport_js addScript $ StaticR js_jquery_fileupload_js
Handler/Reports.hs view
@@ -9,6 +9,8 @@ import ProfilingReport import Control.Applicative import Yesod.Request+import Data.Maybe (listToMaybe)+import Handler.Reports.Helpers (getAllReports, getProfilingReport, postProfilingReport) import qualified Data.Attoparsec as A import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L@@ -19,7 +21,7 @@ getReportsR = do reports <- getAllReports defaultLayout $ do- setTitle "Devel.TKYProf Report"+ setTitle "TKYProf Reports" addWidget $(widgetFile "reports") postReportsR :: Handler ()@@ -33,40 +35,12 @@ report@ProfilingReport {..} <- getProfilingReport reportId let json = T.decodeUtf8 $ A.encode reportCostCentres defaultLayout $ do- setTitle "Devel.TKYProf Report"+ setTitle $ "TKYProf Reports" addScript $ StaticR js_d3_min_js addScript $ StaticR js_d3_layout_min_js addWidget $(widgetFile "reports-id") -- Helper functions-runReports :: STM a -> Handler a-runReports = liftIO . atomically--getReports' :: Handler Reports-getReports' = getReports <$> getYesod--getAllReports :: Handler [(ReportID, ProfilingReport)]-getAllReports = do- rs <- getReports'- runReports $ allReports rs--getAllProfilingReports :: Handler [ProfilingReport]-getAllProfilingReports = map snd <$> getAllReports--getProfilingReport :: ReportID -> Handler ProfilingReport-getProfilingReport reportId = do- rs <- getReports'- mreport <- runReports $ lookupReport reportId rs- case mreport of- Just r -> return r- Nothing -> notFound--postProfilingReport :: ProfilingReport -> Handler ()-postProfilingReport prof = do- rs <- getReports'- reportId <- runReports $ insertReport prof rs- sendResponseCreated (ReportsIdR reportId)- getPostedReport :: Handler FileInfo getPostedReport = do (_, files) <- runRequestBody
+ Handler/Reports/Helpers.hs view
@@ -0,0 +1,47 @@+module Handler.Reports.Helpers+ ( runReports+ , getReports'+ , getAllReports+ , getAllProfilingReports+ , getProfilingReport+ , postProfilingReport+ ) where++import Control.Applicative+import Control.Monad.STM (STM, atomically)+import Control.Monad.Trans (liftIO)+import Model (Reports(..), ReportID, allReports, lookupReport, insertReport)+import ProfilingReport (ProfilingReport)+import TKYProf (Handler, TKYProf(getReports), TKYProfRoute(..))+import Yesod.Core (getYesod, sendResponseCreated)+import Yesod.Handler (notFound)++runReports :: STM a -> Handler a+runReports = liftIO . atomically++getReports' :: Handler Reports+getReports' = getReports <$> getYesod++getAllReports :: Handler [(ReportID, ProfilingReport)]+getAllReports = do+ rs <- getReports'+ runReports $ allReports rs++getAllProfilingReports :: Handler [ProfilingReport]+getAllProfilingReports = map snd <$> getAllReports++getProfilingReport :: ReportID -> Handler ProfilingReport+getProfilingReport reportId = do+ rs <- getReports'+ mreport <- runReports $ lookupReport reportId rs+ case mreport of+ Just r -> return r+ Nothing -> notFound++postProfilingReport :: ProfilingReport -> Handler ()+postProfilingReport prof = do+ rs <- getReports'+ reportId <- runReports $ insertReport prof rs+ sendResponseCreated (ReportsIdR reportId)++
Model.hs view
@@ -1,10 +1,10 @@ {-# LANGUAGE RecordWildCards #-} module Model where-import ProfilingReport+import Control.Applicative+import Control.Concurrent.STM (STM, TVar, newTVar, readTVar, writeTVar) import Data.Map (Map)+import ProfilingReport (ProfilingReport(..)) import qualified Data.Map as M-import Control.Applicative-import Control.Concurrent.STM type ReportID = Integer
TKYProf.hs view
@@ -77,6 +77,7 @@ mmsg <- getMessage (title, bcs) <- breadcrumbs pc <- widgetToPageContent $ do+ addWidget $(Settings.widgetFile "header") widget addLucius $(Settings.luciusFile "default-layout") hamletToRepHtml $(Settings.hamletFile "default-layout")
bin/tkyprof.hs view
@@ -3,25 +3,26 @@ import System.IO (hPutStrLn, stderr) #if PRODUCTION+import Data.Version (showVersion) import Network.Wai.Handler.Warp (Port, run)-import System.Directory (setCurrentDirectory)-import Paths_tkyprof (getDataDir)+import Paths_tkyprof (getDataDir, version) import System.Console.CmdArgs+import System.Directory (setCurrentDirectory) main :: IO () main = do getDataDir >>= setCurrentDirectory TKYProfArg p <- cmdArgs tkyProfArg- hPutStrLn stderr $ "TKYProf launched, listening on http://localhost:" ++ show p+ hPutStrLn stderr $ "TKYProf " ++ showVersion version ++ " launched, listening on http://localhost:" ++ show p ++ "/" withTKYProf $ run p data TKYProfArg = TKYProfArg- { port :: Port+ { port :: Port } deriving (Show, Data, Typeable) tkyProfArg :: TKYProfArg tkyProfArg = TKYProfArg { port = 3000 &= help "Port number" }- &= summary "TKYProf"+ &= summary ("TKYProf " ++ showVersion version) #else import Network.Wai.Middleware.Debug (debug) import Network.Wai.Handler.Warp (run)@@ -37,6 +38,5 @@ import Network.Wai.Handler.Webkit (run) main :: IO ()-main = withTKYProf $ run "Devel.TKYProf"+main = withTKYProf $ run "TKYProf" -}-
− config/favicon.ico
binary file changed (1150 → absent bytes)
+ config/favicon.png view
binary file changed (absent → 538 bytes)
config/routes view
@@ -2,5 +2,5 @@ /reports ReportsR GET POST /reports/#Integer ReportsIdR GET /static StaticR Static getStatic-/favicon.ico FaviconR GET+/favicon.png FaviconR GET /robots.txt RobotsR GET
hamlet/default-layout.hamlet view
@@ -2,15 +2,12 @@ <html lang="en"> <head> <meta charset="utf-8" />- <title>#{pageTitle pc}+ <link rel="shortcut icon" type=image/png href=@{FaviconR}>+ <link href="http://fonts.googleapis.com/css?family=Amaranth:400,700" rel="stylesheet" type="text/css"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">+ <title>#{pageTitle pc} ^{pageHead pc} <body>- <nav #breadcrumbs>- $forall bc <- bcs- <a href=@{fst bc}>#{snd bc}- <span .breadcrumbs-delimiter>>- <a>#{title} $maybe msg <- mmsg <div #message>#{msg} ^{pageBody pc}
+ hamlet/header.hamlet view
@@ -0,0 +1,13 @@+<div #header>+ <nav #breadcrumbs>+ <h1>+ <a href=@{HomeR}>+ <img #logo src=@{StaticR images_tkyprof_logo_orange_png} alt="Home">+ TKYPr+ <span #o>o+ f+ $forall bc <- bcs+ <a href=@{fst bc}>#{snd bc}+ <span .breadcrumbs-delimiter>>+ #{title}+
hamlet/home.hamlet view
@@ -1,12 +1,19 @@-<h1>Devel.TKYProf <section>- <h2>Select your profiling reports+ <h1>Instructions+ <h2>1. Select your profiling reports <form #uploader action=@{ReportsR} method=post enctype=#{Multipart}>- <div #container>- <div #dropbox .box>- <p>Drop in the profiling reports from your desktop.- <div #filedialog .box>- <p>Click to open the file select dialog.+ <div #box-wrapper>+ <div #uploader-dropbox .box>+ <p>Drop files here!+ <div #uploader-filedialog .box>+ <p>Click to select files. <input type=file> <h2>- <a href=@{ReportsR}>View reports+ <a href=@{ReportsR}>2. View reports+ $maybe _ <- listToMaybe reports+ <ul>+ $forall report <- reports+ <li>+ <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}+ $nothing+ <p>There are currently no reports available. First of all, upload your profiling reports please.
hamlet/reports-id.hamlet view
@@ -1,52 +1,21 @@-<h1>The Profiling Report ##{reportId}-<section #summary>- <h1>Summary- <div #report-summary .box>- <dl>- <dt>Timestamp- <dd>#{show reportTimestamp}- <dt>Command line- <dd>#{reportCommandLine}- <dt>Total time- <dd>#{totalSecs reportTotalTime} seconds- <dd>#{totalTicks reportTotalTime} ticks @ #{resolution reportTotalTime} ms- <dt>Total allocations- <dd>#{totalAllocBytes reportTotalAlloc} bytes- <!--- <div #hot-cost-centres .box>- <table>- <caption>Hot cost centres- <thead>- <tr>- <th>Cost centre- <th>Module- <th>%time- <th>%alloc- <tbody>- $forall bcc <- reportHotCostCentres- <tr>- <td>#{briefCostCentreName bcc}- <td>#{briefCostCentreModule bcc}- <td>#{briefCostCentreTime bcc}- <td>#{briefCostCentreAlloc bcc}- -->+<h1>Time and Allocation Profiling Report ##{reportId} <section #cost-centres> <header>- <h1>Cost centres- <button #time>Time report- <button #alloc>Alloc report- </header>+ <h1>Cost centres:+ <div .button-group>+ <div #time .button .active>Time profiling+ <div #alloc .button>Alloc profiling <div #chart-container> <figure #chart> <div #sidebox> <div #current-node>- <h3>Current node+ <h2>Current node <dl> <dt>Module <dd #current-node-module> <dt>Name <dd #current-node-name>- <dt>Node number+ <dt>Number <dd #current-node-number> <dt>Entries <dd #current-node-entries>@@ -59,6 +28,18 @@ <dt>Inherited %alloc <dd #current-node-inh-alloc> <div #children>- <h3>Children+ <h2>Children <ol>-+<section #summary>+ <h1>Summary+ <div #report-summary .box>+ <dl>+ <dt>Timestamp+ <dd>#{show reportTimestamp}+ <dt>Command line+ <dd>#{reportCommandLine}+ <dt>Total time+ <dd>#{totalSecs reportTotalTime} seconds+ <dd>#{totalTicks reportTotalTime} ticks @ #{resolution reportTotalTime} ms+ <dt>Total allocations+ <dd>#{totalAllocBytes reportTotalAlloc} bytes
hamlet/reports.hamlet view
@@ -1,6 +1,9 @@-<h1>All reports-<ul>- $forall report <- reports- <li>- <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}-+<section>+ <h1>All reports+ $maybe _ <- listToMaybe reports+ <ul>+ $forall report <- reports+ <li>+ <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}+ $nothing+ <p>There are currently no reports available. First of all, upload your profiling reports please.
lucius/default-layout.lucius view
@@ -1,8 +1,38 @@-h1, h2 {- text-align: center;+/* body */+body {+ color: #f3f3e3;+ background: #212121;+ font-family: sans-serif; } -.breadcrumbs-delimiter {- margin-left: 0.5em;- margin-right: 0.5em;+/* hx */+h1, h2, h3, h4 {+ font-family: 'Amaranth', sans-serif;+ font-weight: 400;+}++h1 {+ font-size: 2em;+}++h2 {+ font-size: 1.5em;+}++/* a */+a {+ color: #f3f3e3;+ text-decoration: none;+}++section a:hover {+ color: #e6550d;+ text-decoration: underline;+}++/* footer */+footer {+ text-align: right;+ font-size: 0.75em;+ visibility: hidden; }
+ lucius/header.lucius view
@@ -0,0 +1,32 @@+#header {+ height: 38px;+ width: 100%;+}++#header h1 {+ font-family: 'Amaranth', sans-serif;+ font-weight: 700;+ font-size: 30px;+ margin: 0px;+ margin-right: 10px;+ display: inline;+}++#header h1 #logo {+ margin-right: 5px;+}++#header h1 #o {+ color: #e6550d;+}++/* breadcrumbs */+#breadcrumbs {+ font-family: sans-serif;+ font-size: 0.75em;+}++.breadcrumbs-delimiter {+ margin-left: 0.5em;+ margin-right: 0.5em;+}
lucius/home.lucius view
@@ -1,4 +1,4 @@-#container {+#box-wrapper { width: 100%; display: -webkit-box;@@ -17,12 +17,18 @@ .box { width: 50%; text-align: center;+ box-sizing: border-box; } -#dropbox {+/* dropbox */+#uploader-dropbox { height: 200px;- border: 2px dashed #0687FF;+ border: 2px dashed #fd8d38; + -webkit-border-radius: 10px;+ -moz-border-radius: 10px;+ border-radius: 10px;+ display: -webkit-box; display: -moz-box; display: box;@@ -34,12 +40,13 @@ -webkit-box-pack: center; -moz-box-pack: center; box-pack: center;+} - -webkit-border-radius: 10px;- -khtml-border-radius: 10px;- -moz-border-radius: 10px;- border-radius: 10px;+#uploader-dropbox:hover {+ border: 2px solid #e6550d; } -#filedialog {+/* file dialog */+#uploader-filedialog {+ /* do nothing */ }
lucius/reports-id.lucius view
@@ -1,28 +1,62 @@-#report-summary {- width: 100%;+/* title and buttons */+#cost-centres h1 {+ display: inline;+ margin-right: 15px;+ font-size: 1.5em; } -/*-#hot-cost-centres {- width: 70%;- float: right;- border-left: 1px solid;+#cost-centres .button-group,+#cost-centres .button-group div {+ display: inline;+ font-family: 'Amaranth', sans-serif;+ font-weight: 700;+ font-size: 1.0em; }-*/ -#cost-centres {+#cost-centres .button {+ border: 1.5px solid transparent;+ padding-left: 4px;+ padding-right: 4px;+ cursor: pointer; } -#time {- display: inline;+#cost-centres .button:hover {+ /* border: 1.5px solid #fd8d38; */+ border: 1.5px solid #f3f3e3; } -#alloc {- display: inline;+#cost-centres .active {+ /* border: 1.5px solid #fd8d38; */+ /* background: #fd8d38; */+ border: 1.5px solid #f3f3e3;+ background: #f3f3e3;+ color: #212121; } +#cost-centres .button:first-child {+ -webkit-border-top-left-radius: 0.5em;+ -moz-border-top-left-radius: 0.5em;+ border-top-left-radius: 0.5em;+ -webkit-border-bottom-left-radius: 0.5em;+ -moz-border-bottom-left-radius: 0.5em;+ border-bottom-left-radius: 0.5em;+}++#cost-centres .button:last-child {+ -webkit-border-top-right-radius: 0.5em;+ -moz-border-top-right-radius: 0.5em;+ border-top-right-radius: 0.5em;+ -webkit-border-bottom-right-radius: 0.5em;+ -moz-border-bottom-right-radius: 0.5em;+ border-bottom-right-radius: 0.5em;+}+++/* chart */ #chart-container { width: 100%;+ font-size: 0.85em;+ display: -webkit-box; display: -moz-box; display: box;@@ -39,20 +73,47 @@ } #chart path {- stroke: #fff;+ stroke: #212121;+ stroke-width: 0.5; fill-rule: evenodd;+ opacity: 1; } +/* sidebox */ #sidebox {- width: 200px;+ background: #353535;+ padding: 1em;+ padding-top: 0.5em;+ width: 18em;+ min-height: 37em; -webkit-box-ordinal-group: 2; -moz-box-ordinal-group: 2; box-ordinal-group: 2;+ text-overflow: ellipsis;+ overflow: hidden;++ -webkit-border-radius: 10px;+ -moz-border-radius: 10px;+ border-radius: 10px; } -#current-node {+#sidebox dt {+ float: left; } -#children {+#sidebox dd {+ margin-left: 10em; } +/* summary */+#report-summary {+ font-size: 0.85em;+}++#report-summary dt {+ float: left;+}++#report-summary dd {+ margin-left: 10em;+}
+ static/images/tkyprof-logo-orange.png view
binary file changed (absent → 783 bytes)
tkyprof.cabal view
@@ -1,5 +1,5 @@ name: tkyprof-version: 0.0.4+version: 0.0.5.1 license: BSD3 license-file: LICENSE author: Mitsutoshi Aoe@@ -19,13 +19,14 @@ static/js/jquery.iframe-transport.js static/js/jquery.pjax.js static/js/jquery.ui.widget.js+ static/images/*.png+ config/favicon.png++extra-source-files: config/routes hamlet/*.hamlet julius/*.julius lucius/*.lucius- config/favicon.ico -extra-source-files: config/routes- flag production description: Build the production executable. default: True@@ -85,6 +86,7 @@ other-modules: TKYProf Handler.Home Handler.Reports+ Handler.Reports.Helpers Model Paths_tkyprof ProfilingReport