1
0
Fork 0
mirror of https://code.sup39.dev/repos/Wqawg synced 2025-01-07 20:36:45 +09:00
vervis/src/Vervis/ActivityStreams.hs
2019-02-14 22:13:58 +00:00

224 lines
5.5 KiB
Haskell

{- This file is part of Vervis.
-
- Written in 2018 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.ActivityStreams
( Actor (..)
, ActivityStreams2 (..)
, provideAS2
, makeActor
)
where
import Control.Monad.Trans.Writer
import Data.Aeson (pairs)
import Data.Monoid
import Vervis.Import
import Vervis.Model.Ident
-- AS2 is divided into core and extensions-for-common-social-web-use-cases, I'm
-- starting with the core, looking at the AS2 vocab spec
{-
data Object = Object
{ objectAttachment ::
, objectAttributedTo ::
, objectAudience ::
, objectContent ::
, objectContext ::
, objectName ::
, objectEndTime ::
, objectGenerator ::
, objectIcon ::
, objectImage ::
, objectInReplyTo ::
, objectLocation ::
, objectPreview ::
, objectPublished ::
, objectReplies ::
, objectStartTime ::
, objectSummary ::
, objectTag ::
, objectUpdated ::
, objectUrl ::
, objectTo ::
, objectBto ::
, objectCc ::
, objectBcc ::
, objectMediaType ::
, objectDuration ::
}
data Link = Link
{ linkHref ::
, linkRel ::
, linkMediaType ::
, linkName ::
, linkHrefLang ::
, linkHeight ::
, linkWidth ::
, linkPreview ::
}
data Activity = Activity
{ activityAsObject :: Object
, activityActor ::
, activityObject ::
, activityTarget ::
, activityResult ::
, activityOrigin ::
, activityInstrument ::
}
data IntransitiveActivity = IntransitiveActivity
{ iactivityAsObject :: Object
, iactivityActor ::
, iactivityTarget ::
, iactivityResult ::
, iactivityOrigin ::
, iactivityInstrument ::
}
data Collection = Collection
{ collectionAsObject :: Object
, collectionTotalItems ::
, collectionCurrent ::
, collectionFirst ::
, collectionLast ::
, collectionItems ::
}
data OrderedCollection = OrderedCollection
{ ocollectionAsCollection :: Collection
}
data CollectionPage = CollectionPage
{ collectionPageAsCollection :: Collection
, collectionPagePartOf ::
, collectionPageNext ::
, collectionPagePrev ::
}
data OrderedCollectionPage = OrderedCollectionPage
{ orderedCollectionPageAsCollectionPage :: CollectionPage
, orederdCollectionPageStartIndex ::
}
-- Now come the extended types
-- Activity types - I'm skipping them for now
-- Actor types
data Application = Application
{ applicationAsObject :: Object
}
data Group = Group
{ groupAsObject :: Object
}
data Organization = Organization
{ organizationAsObject :: Object
}
data Person = Person
{ personAsObject :: Object
}
data Service = Service
{ serviceAsObject :: Object
}
-}
-- Actor objects in AP
data Actor = Actor
{ -- Requirements
actorId :: Text
, actorType :: Text
-- Must
, actorInbox :: Text
, actorOutbox :: Text
-- Should
--, actorFollowing
--, actorFollowers
-- May
--, actorLiked
--, actorStreams
--, actorPreferredUsername
--, actorEndpoints
}
fields a =
[ "@context" .= ("https://www.w3.org/ns/activitystreams" :: Text)
, "id" .= actorId a
, "type" .= actorType a
, "inbox" .= actorInbox a
, "outbox" .= actorOutbox a
]
instance ToJSON Actor where
toJSON = object . fields
toEncoding = pairs . mconcat . fields
-- NEXT:
--
-- * Figure out how to detect the client wanting AS2 / AP
-- * Send minimal simple actor per user
typeActivityStreams2 :: ContentType
typeActivityStreams2 = "application/activity+json"
typeActivityStreams2LD :: ContentType
typeActivityStreams2LD =
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
data ActivityStreams2 = ActivityPubActor Actor
instance ToContent ActivityStreams2 where
toContent (ActivityPubActor a) = toContent $ toEncoding a
{-
instance ToTypedContent ActivityStreams2 where
toTypedContent = TypedContent typeActivityStreams2 . toContent
instance HasContentType ActivityStreams2 where
getContentType _ = typeActivityStreams2
data ActivityStreams2LD = ActivityStreams2LD ActivityStreams2
instance ToContent ActivityStreams2LD where
toContent (ActivityStreams2LD a) = toContent a
instance ToTypedContent ActivityStreams2LD where
toTypedContent = TypedContent typeActivityStreams2LD . toContent
instance HasContentType ActivityStreams2LD where
getContentType _ = typeActivityStreams2LD
-}
provideAS2 :: Monad m => ActivityStreams2 -> Writer (Endo [ProvidedRep m]) ()
provideAS2 as2 = do
provideRepType typeActivityStreams2 $ return as2
provideRepType typeActivityStreams2LD $ return as2
makeActor ur shr =
Actor
{ actorId = ur $ SharerR shr
, actorType = "Person"
, actorInbox = ur $ SharerR shr
, actorOutbox = ur $ error "We don't have outboxes yet"
}