{-# OPTIONS_GHC -F -pgmF trhsx #-} {-# LANGUAGE RecordWildCards #-} module DarcsDen.Pages.Repository where import Data.Digest.Pure.MD5 (md5) import Data.List (sortBy) import Data.Maybe (fromJust) import Data.Time (UTCTime, formatTime) import HSP import System.Locale (defaultTimeLocale) import qualified Data.ByteString as BS import DarcsDen.Handler.Repository.Browse (RepoItem(..)) import DarcsDen.Handler.Repository.Changes ( FileChange(..) , PatchLog(..) , PatchChange(..) , Summary(..) ) import DarcsDen.Handler.Repository.Forks (Fork(..), canMerge) import DarcsDen.Pages.HSPage ( HSPage ) import DarcsDen.Pages.Base import DarcsDen.Pages.Util ( repoForkSourceDescription, links, links' ) import DarcsDen.Settings import DarcsDen.State.Comment import DarcsDen.State.Issue import DarcsDen.State.Repository import DarcsDen.State.Session import DarcsDen.State.User import DarcsDen.Util hiding (paginate) repoBase' :: User -> Bool -> Repository -> String -> HSP XML -> HSP XML -> HSP XML -> HSPage repoBase' _ i r t b c l s = base t i <% rOwner r %> -> <% rName r %> <% b %>
<% l %>

<% rDescription r %> <% repoForkSourceDescription r %> <% if rWebsite r /= "" then <% (<% rWebsite r %>) %> else <% "" %> %>

<% c %>
s repoBase :: User -> Bool -> Repository -> String -> HSP XML -> HSP XML -> HSPage repoBase u i r t b c s = repoBase' u i r t b c (links r (Just (rOwner r) == sUser s)) s init :: [(String, String)] -> HSPage init is = base "init" False init

initialize

<% field (input' is "name") "name" "" %> <% field (input' is "description") "description" "" %> <% field (input' is "website") "website" "" %> -- <% field (input' is "bootstrap") "bootstrap" "" %> <% field (checkbox' is "private") "private?" "" %> <% submit "create repository" %>
repo :: User -> Repository -> [RepoItem] -> [RepoItem] -> Maybe String -> Bool -> HSPage repo u r files path readme member sess = repoBase' u True r (uName u ++ "'s " ++ rName r) -> files (filesList (null files)) lks sess where lks = if (member || (Just (rOwner r) == sUser sess)) then links' r [
  • repository settings
  • ,
  • delete
  • ,
  • add file
  • ] else links r False filesList :: Bool -> HSP XML filesList True =

    nothing here yet!

    <% if Just (rOwner r) == sUser sess then ownerMessage else if member then memberMessage else otherMessage %>
    where ownerMessage =

    push your code to <% uName u %>@<% hostname %>:<% rName r %> to get started

    memberMessage =

    push your code to <% fromJust (sUser sess) %><% hostname %>:<% rOwner r %>/<% rName r %> to get started

    otherMessage =

    move along, citizen

    filesList False =

    root <% map (\p -> / <% iName p %>) path %>

    <% case readme of Nothing -> <% "" %> Just s -> <%
    <% cdata s %>
    %> %>
    file :: RepoItem -> HSP XML file f =
  • <% iName f %>
  • edit :: User -> Repository -> [User] -> [(String, String)] -> HSPage edit u r ms is = repoBase u False r "edit" -> edit
    <% field (input "name" (rName r)) "name" "" %> <% field (input "description" (rDescription r)) "description" "" %> <% field (input "website" (rWebsite r)) "website" "" %> <% if issuetrackers then <% field (checkbox (rIssueTracker r) is "issuetracker") "issue tracker ?" "" %> else <% "" %> %> <% field (checkbox (rIsPrivate r) is "private") "private ?" "" %> <% field (input' is "add-members") "add members" "comma separated" %> <% if not (null ms) then <%
      <% map (\m@(User { uID = Just uid }) ->
    • <% cdata " " %> <% uName m %>
    • ) ms %>

    %> else <% "" %> %> <% submit "update repository" %>

    Build Packs

    delete :: User -> Repository -> HSPage delete u r = repoBase u False r "delete" -> delete

    are you sure you want to delete this repository?

    this action cannot be undone.

    or cancel
    fork :: User -> Repository -> String -> HSPage fork u r n = repoBase u False r "fork" -> fork

    you already have a repository named "<% n %>"

    please create an alternative name:

    <% field (input "name" (n ++ "-")) "new name" "" %> <% submit "fork!" %>
    issues :: User -> Repository -> String -> [Issue] -> HSPage issues u r t is s = repoBase u True r t -> <% t %>
    <% issueLinks r %> <% if not (null is) then else

    no issues!

    there don't seem to be any issues for this project.

    %>
    s issuesByTags :: User -> Repository -> [Issue] -> [[String]] -> HSPage issuesByTags u r is ts s = repoBase u False r ("issues tagged with " ++ humanOr ts) -> issues
    <% issueLinks r %> <% if not (null is) then else

    no issues tagged with <% humanOr ts %>

    there don't seem to be any issues with <% if length ts == 1 then "that tag" else "those tags" %>.

    %>
    s where humanAnd [] = "" humanAnd [t] = t humanAnd [a, b] = a ++ " and " ++ b humanAnd (x:ys) = x ++ ", " ++ humanAnd ys humanOr [] = "" humanOr [t] = humanAnd t humanOr [a, b] = humanAnd a ++ " or " ++ humanAnd b humanOr (x:ys) = humanAnd x ++ ", " ++ humanOr ys issueLinks :: Repository -> HSP XML issueLinks r =
    open closed all new issue
    renderIssue :: Repository -> Issue -> HSP XML renderIssue r i =
  • #<% show $ iNumber i %>
    <% iSummary i %> <% if not (null (iTags i)) then <%
      <% map (\t ->
    • <% t %>
    • ) (iTags i) %>
    %> else <% "" %> %>
    reported by <% iOwner i %> <% cdata " " %> <% formatTime defaultTimeLocale "%c" (iCreated i) %> <% if not (iCreated i == iUpdated i) then <% , updated <% formatTime defaultTimeLocale "%c" (iUpdated i) %> %> else <% "" %> %>
  • issue :: User -> Repository -> Issue -> [Comment] -> HSPage issue u r i cs s = repoBase u True r ("#" ++ show (iNumber i) ++ ": " ++ iSummary i) -> issue

    #<% show $ iNumber i %> <% iSummary i %>

    <% do mo <- getUser (iOwner i) case mo of Just o -> Nothing -> %> <% cdata $ doMarkdown (iDescription i) %>
    <% case sUser s of Just _ ->
    {- -}
      <% map (\t ->
    • <% t %>
    • ) (iTags i) %>

    revise issue

    Nothing -> please log in to comment %>
    s where add = issueURL r i ++ "/comment" renderComment c =
  • <% do ma <- getUser (cAuthor c) case ma of Just a ->
    <% if not (null (uFullName a)) then uFullName a else uName a %>
    Nothing ->
    unknown
    %> <% if not (null (cChanges c)) then <% %> else <% "" %> %>
    <% cdata (doMarkdown (cBody c)) %>
  • renderChange (AddTag t) =
  • added tag <% t %>
  • renderChange (RemoveTag t) =
  • removed tag <% t %>
  • renderChange (Summary _ t) =
  • summary changed to "<% t %>"
  • renderChange (Description _ _) =
  • description updated
  • renderChange (Closed True) =
  • status set to closed
  • renderChange (Closed False) =
  • status set to open
  • newIssue :: User -> Repository -> HSPage newIssue u r = repoBase u False r "new issue" -> new issue

    new issue

    {- disable hard-coded assignment & issue type fields, don't want to encourage enhancement issues right now -}
    patches :: User -> Repository -> [Fork] -- ^public forks -> [Fork] -- ^private forks owned by the current user -> HSPage patches u r fs opfs s = repoBase u True r "branches" -> branches
    <% patchesForm %>
    s where mergeablepatchesexist = any (not . null . fPatches) $ fs ++ opfs canmerge = canMerge (sUser s) r patchesForm :: HSP XML patchesForm =
    <% map fork' opfs %> <% map fork' fs %> <% if mergeablepatchesexist && canmerge then <%

    <% submit "merge selected" %>
    %> else <% "" %> %>
    <% if mergeablepatchesexist then <% "" %> else <%

    There doesn't seem to be anything new.

    %> %>
    fork' (Fork f cs) = <%

    <% rOwner f %>'s <% rName f %>

    <% map (change' f) cs %>
    %> change' :: Repository -> PatchLog -> HSP XML change' f p = <% if canmerge then <% %> else <% "" %> %>

    <% pName p %>

    <% author p %> <% formatTime defaultTimeLocale "%c" (pDate p) %> changes :: User -> Repository -> [PatchLog] -> Int -> Int -> HSPage changes u r cs p tp = repoBase u True r "changes" -> changes
    <% paginate (repoURL r ++ "/changes") p tp %> <% map (change r) cs %>
    <% paginate (repoURL r ++ "/changes") p tp %>
    change :: Repository -> PatchLog -> HSP XML change f p = -- <% -- if canmerge -- then -- <% -- -- -- -- %> -- else <% "" %> -- %>

    <% pName p %>

    <% if not (null (pLog p)) then <%
    <% cdata (pLog p) %>
    %> else <% "" %> %> <% author p %> <% formatTime defaultTimeLocale "%c" (pDate p) %> author :: PatchLog -> HSP XML author p | pIsUser p = <% pAuthor p %> | otherwise = <% pAuthor p %> changesAtom :: User -> Repository -> [PatchLog] -> HSPage changesAtom u r cs _ = <% uName u %>/<% rName r %> changes <% repoURL r ++ "/changes/atom" %> <% if not (null cs) then <% <% asAtomDate latest %> %> else <% "" %> %> <% uName u %> <% userURL u %> <% map entry cs %> where asAtomDate :: UTCTime -> String asAtomDate = formatTime defaultTimeLocale "%FT%TZ" latest :: UTCTime latest = head . sortBy (flip compare) . map pDate $ cs entry :: PatchLog -> HSP XML entry p = <% pName p %> <% repoURL r ++ "/patch/" ++ pID p %> <% asAtomDate (pDate p) %> <% pAuthor p %> <% if pIsUser p then <% <% baseUrl ++ pAuthor p %> %> else <% "" %> %> <% pName p %> blob :: User -> Repository -> [RepoItem] -> Maybe (Either String BS.ByteString) -> HSPage blob u r fs b s = repoBase' u False r (iName file) -> files

    root <% map (\f -> <% / <% iName f %> %>) (Prelude.init fs) %> / <% iName file %>

    <% case b of Nothing ->

    sorry! this file is too gigantic to display. click the filename above to view the source.

    Just (Left md) ->
    <% cdata md %>
    Just (Right source) ->
    <% cdata . fromBS $ source %>
    %>
    lns s where file :: RepoItem file = last fs member = case sUser s of Just un -> (un `elem` rOwner r:rMembers r) Nothing -> False lns = if member then links' r [
  • edit file
  • ] else links' r [] addFile :: User -> Repository -> [RepoItem] -> HSPage addFile u r fs = repoBase u False r file -> add file/directory

    root <% map (\f -> <% / <% iName f %> %>) fs %>

    <%
    <% field (input "filename" "") "File Name" "" %> <% field ft_opts "File type" "" %> <% field (input "message" "") "Message" "" %> <% submit "Create file/directory" %>
    %>
    where file = if null fs then "" else tail $ iPath $ last $ fs ft_opts =
    file
    directory
    editFile :: User -> Repository -> [RepoItem] -> String -> String -> HSPage editFile u r fs mime contents = repoBase u False r (iName file) -> edit file

    root <% map (\f -> <% / <% iName f %> %>) (Prelude.init fs) %> / <% iName file %>

    <%

    <% field (input "message" "") "Message" "" %> <% submit "Update code" %>
    %>
    where file :: RepoItem file = last fs explore :: [(Repository, [Repository])] -> Int -> Int -> HSPage explore rs p tp = base "all repos" True all repos

    all repositories

    <% paginate (baseUrl ++ "explore") p tp %> <% paginate (baseUrl ++ "explore") p tp %>
    where repo' :: (Repository, [Repository]) -> HSP XML repo' (r, fs) =
  • <% rName r %> :: <% rOwner r %>

    <% rDescription r %>

    <% if length fs > 0 then <%

    forks:

    %> else <% "" %> %>
  • patch :: User -> Repository -> String -> HSPage patch u r pId = repoBase u False r "patch" -> patch

    Fetching patch details...

    where rpurl = repoURL r ++ "/renderedpatch/" ++ pId renderedpatchHtml :: User -> Repository -> PatchLog -> [Summary] -> [PatchChange]-> HSPage renderedpatchHtml _ r p ss cs _ = do

    patch

    <% if not (null ss) then <% summaries ss %> else <% "" %> %> <% if not (null cs) then <% diffs cs %> else <% "" %> %>
    where summaries :: [Summary] -> HSP XML summaries ss' =

    summary

    summary :: Summary -> HSP XML summary (Removed n) =
  • <% n %>
  • summary (Added n) =
  • <% n %>
  • summary (Replaced n f t) =
  • <% n %> replaced <% f %> with <% t %>
  • summary (Modified f) =
  • <% f %>
  • summary (Preference n f t) =
  • changed "<% n %>" preference from "<% f %>" to "<% t %>"
  • diffs :: [PatchChange] -> HSP XML diffs cs' =

    changes

    where (displayablecs, numelided) = takeUpTo maxPatchDisplaySize cs' takeUpTo :: Int -> [PatchChange] -> ([PatchChange],Int) takeUpTo m ps = (reverse ds, length es) where (ds, es) = takeUpTo' m [] ps -- XXX likely inefficient takeUpTo' :: Int -> [PatchChange] -> [PatchChange] -> ([PatchChange],[PatchChange]) takeUpTo' _ ds [] = (ds, []) takeUpTo' m ds (e:es) | size > m = (ds, (e:es)) | otherwise = (takeUpTo' m ds' es) where size = sum $ map hunkSize ds' ds' = e:ds hunkSize :: PatchChange -> Int hunkSize (FileChange{cfType=FileHunk{..}}) = BS.length fchRemove + BS.length fchAdd hunkSize _ = 0 diff :: PatchChange -> HSP XML diff c =
  • <% cfName c %> <% cdata " :: " %> line <% show (fchLine (cfType c)) %>
    <% cdata . fromBS $ fchRemove (cfType c) %>
    <% cdata . fromBS $ fchAdd (cfType c) %>
  • gravatar :: User -> Int -> String gravatar u s = "http://gravatar.com/avatar/" ++ email ++ "?s=" ++ show s ++ "&d=identicon" where email = show . md5 . toLBS $ uEmail u tagURL :: Repository -> String -> String tagURL r t = repoURL r ++ "/issues/tag/" ++ t