Eventually-decentralized project hosting and management platform
Clone
HTTPS:
darcs clone https://vervis.peers.community/repos/WvWbo
SSH:
darcs clone USERNAME@vervis.peers.community:WvWbo
Tags
TODO
Fetch.hs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | {- This file is part of Vervis.
-
- Written in 2022 by fr33domlover <fr33domlover@riseup.net>.
-
- ♡ Copying is an act of love. Please copy, reuse and share.
-
- The author(s) have dedicated all copyright and related and neighboring
- rights to this software to the public domain worldwide. This software is
- distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along
- with this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
-}
module Vervis.Fetch
( Result (..)
, httpGetRemoteTip
, httpGetRemoteRepo
)
where
import Control.Applicative
import Control.Exception.Base
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Except
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Reader
import Data.Align
import Data.Barbie
import Data.Bifunctor
import Data.Bifoldable
import Data.Bitraversable
import Data.Foldable
import Data.Functor
import Data.Functor.Identity
import Data.List.NonEmpty (NonEmpty (..))
import Data.Maybe
import Data.Text (Text)
import Data.These
import Data.Time.Clock
import Data.Traversable
import Database.Persist hiding (deleteBy)
import Database.Persist.Sql hiding (deleteBy)
import Network.HTTP.Client
import System.Directory
import System.Exit
import System.FilePath
import System.IO.Temp
import System.Process.Typed
import Text.Blaze.Html.Renderer.Text
import Yesod.Core hiding (logError, logWarn, logInfo, logDebug)
import Yesod.Persist.Core
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import qualified Data.Text.Lazy as TL
import Database.Persist.JSON
import Development.PatchMediaType
import Network.FedURI
import Web.ActivityPub hiding (Patch, Ticket, Follow, Repo (..), ActorLocal (..), ActorDetail (..), Actor (..))
import Web.Text
import Yesod.ActivityPub
import Yesod.FedURI
import Yesod.Hashids
import Yesod.MonadSite
import qualified Web.ActivityPub as AP
import Control.Monad.Trans.Except.Local
import Data.Either.Local
import Database.Persist.Local
import qualified Data.Git.Local as G (createRepo)
import qualified Data.Text.UTF8.Local as TU
import qualified Darcs.Local.Repository as D (createRepo)
import Vervis.Access
import Vervis.ActivityPub
import Vervis.Cloth
import Vervis.Data.Actor
import Vervis.Data.Collab
import Vervis.Data.Ticket
import Vervis.Web.Delivery
import Vervis.FedURI
import Vervis.Foundation
import Vervis.Model
import Vervis.Model.Ident
import Vervis.Model.Role
import Vervis.Model.Workflow
import Vervis.Model.Ticket
import Vervis.Path
import Vervis.Persist.Actor
import Vervis.Persist.Collab
import Vervis.Recipient
import Vervis.RemoteActorStore
import Vervis.Settings
import Vervis.Query
import Vervis.Ticket
data Result
= ResultSomeException SomeException
| ResultIdMismatch
| ResultGetError APGetError
| ResultNotActor
deriving Show
fetchRepoE :: (MonadSite m, SiteEnv m ~ App) => Host -> LocalURI -> ExceptT Result m (AP.Repo URIMode)
fetchRepoE h lu = do
manager <- asksSite getHttpManager
let apRepoId = AP.actorId . AP.actorLocal . AP.repoActor
ExceptT $ first (maybe ResultIdMismatch ResultGetError) <$>
fetchAPID' manager apRepoId h lu
insertRemoteActor
:: MonadIO m
=> Host
-> LocalURI
-> AP.Actor URIMode
-> ReaderT SqlBackend m RemoteActorId
insertRemoteActor h lu (AP.Actor local detail) = do
iid <- either entityKey id <$> insertBy' (Instance h)
roid <- either entityKey id <$> insertBy' (RemoteObject iid lu)
let ra = RemoteActor
{ remoteActorIdent = roid
, remoteActorName =
AP.actorName detail <|> AP.actorUsername detail
, remoteActorInbox = AP.actorInbox local
, remoteActorFollowers = AP.actorFollowers local
, remoteActorErrorSince = Nothing
}
either entityKey id <$> insertBy' ra
httpGetRemoteTip
:: (MonadUnliftIO m, MonadSite m, SiteEnv m ~ App)
=> FedURI
-> ExceptT Result m
( VersionControlSystem
, RemoteActorId
, FedURI
, Maybe (LocalURI, Text)
)
httpGetRemoteTip (ObjURI host localURI) = do
repoOrBranch <- fetchTipE host localURI
case repoOrBranch of
Left repo -> do
remoteActorID <-
lift $ runSiteDB $
insertRemoteActor host localURI $ AP.repoActor repo
let uClone = ObjURI host $ NE.head $ AP.repoClone repo
return (AP.repoVcs repo, remoteActorID, uClone, Nothing)
Right (AP.Branch name _ luRepo) -> do
repo <- fetchRepoE host luRepo
remoteActorID <-
lift $ runSiteDB $
insertRemoteActor host luRepo $ AP.repoActor repo
let uClone = ObjURI host $ NE.head $ AP.repoClone repo
return (AP.repoVcs repo, remoteActorID, uClone, Just (localURI, name))
where
fetchTipE h lu = do
manager <- asksSite getHttpManager
ExceptT $ first (maybe ResultIdMismatch ResultGetError) <$>
fetchTip manager h lu
httpGetRemoteRepo
:: (MonadUnliftIO m, MonadSite m, SiteEnv m ~ App)
=> FedURI
-> ExceptT Result m (VersionControlSystem, RemoteActorId, FedURI)
httpGetRemoteRepo (ObjURI host localURI) = do
repo <- fetchRepoE host localURI
remoteActorID <-
lift $ runSiteDB $
insertRemoteActor host localURI $ AP.repoActor repo
let uClone = ObjURI host $ NE.head $ AP.repoClone repo
return (AP.repoVcs repo, remoteActorID, uClone)
|