Representation.hs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# LANGUAGE TemplateHaskell #-}
  3. module Codec.ActivityStream.Representation where
  4. import Control.Applicative
  5. import Control.Lens hiding ((.=))
  6. import Data.Aeson ( FromJSON(..)
  7. , ToJSON(..)
  8. , Value
  9. , fromJSON
  10. , object
  11. , (.=)
  12. , (.:)
  13. , (.:?)
  14. )
  15. import qualified Data.Aeson as Ae
  16. import Data.Aeson.TH
  17. import Data.DateTime
  18. import qualified Data.HashMap.Strict as HM
  19. import Data.Maybe (catMaybes)
  20. import Data.Text (Text)
  21. import Network.URI
  22. import Codec.ActivityStream.Internal
  23. data Verb ext
  24. = Post
  25. | VerbExt ext
  26. deriving (Eq, Show)
  27. instance FromJSON ext => FromJSON (Verb ext) where
  28. parseJSON (Ae.String "post") = return Post
  29. parseJSON ext = VerbExt `fmap` parseJSON ext
  30. instance ToJSON ext => ToJSON (Verb ext) where
  31. toJSON Post = Ae.String "post"
  32. toJSON (VerbExt ext) = toJSON ext
  33. data MediaLink = MediaLink
  34. { _mlDuration :: Maybe Int
  35. , _mlHeight :: Maybe Int
  36. , _mlURL :: Text
  37. , _mlWidth :: Maybe Int
  38. } deriving (Eq, Show)
  39. makeLenses ''MediaLink
  40. deriveJSON (commonOpts "_ml") ''MediaLink
  41. data Object objType = Object
  42. { _oAttachments :: [Object objType]
  43. , _oAuthor :: Maybe (Object objType)
  44. , _oContent :: Maybe Text
  45. , _oDisplayName :: Maybe Text
  46. , _oDownstreamDuplicates :: [URI]
  47. , _oId :: Maybe URI
  48. , _oImage :: Maybe MediaLink
  49. , _oObjectType :: Maybe objType
  50. , _oPublished :: Maybe DateTime
  51. , _oSummary :: Maybe Text
  52. , _oUpdated :: Maybe DateTime
  53. , _oUpstreamDuplicates :: [URI]
  54. , _oURL :: Maybe URI
  55. , _oRest :: [(Text, Value)]
  56. } deriving (Eq, Show)
  57. makeLenses ''Object
  58. objectFields :: [Text]
  59. objectFields =
  60. [ "attachments"
  61. , "author"
  62. , "content"
  63. , "displayName"
  64. , "downstreamDuplicates"
  65. , "id"
  66. , "image"
  67. , "objectType"
  68. , "published"
  69. , "summary"
  70. , "updated"
  71. , "upstreamDuplicates"
  72. , "url"
  73. ]
  74. instance FromJSON objType => FromJSON (Object objType) where
  75. parseJSON (Ae.Object o) =
  76. Object <$> fmap go (o .:? "attachments")
  77. <*> o .:? "author"
  78. <*> o .:? "content"
  79. <*> o .:? "displayName"
  80. <*> fmap go (o .:? "downstreamDuplicates")
  81. <*> o .:? "id"
  82. <*> o .:? "image"
  83. <*> o .:? "objectType"
  84. <*> o .:? "published"
  85. <*> o .:? "summary"
  86. <*> o .:? "updated"
  87. <*> fmap go (o .:? "upstreamDuplicates")
  88. <*> o .:? "url"
  89. <*> pure rest
  90. where rest = HM.toList (foldr HM.delete o objectFields)
  91. go :: Maybe [a] -> [a]
  92. go Nothing = []
  93. go (Just xs) = xs
  94. instance ToJSON objType => ToJSON (Object objType) where
  95. toJSON obj = object (attrs ++ _oRest obj)
  96. where attrs = catMaybes
  97. [ "attachments" .=! _oAttachments obj
  98. , "author" .=? _oAuthor obj
  99. , "content" .=? _oContent obj
  100. , "displayName" .=? _oDisplayName obj
  101. , "downstreamDuplicates" .=! _oDownstreamDuplicates obj
  102. , "id" .=? _oId obj
  103. , "image" .=? _oImage obj
  104. , "objectType" .=? _oObjectType obj
  105. , "published" .=? _oPublished obj
  106. , "summary" .=? _oSummary obj
  107. , "updated" .=? _oUpdated obj
  108. , "upstreamDuplicates" .=! _oUpstreamDuplicates obj
  109. , "url" .=? _oURL obj
  110. ]
  111. (.=?) :: ToJSON a => Text -> Maybe a -> Maybe (Text, Value)
  112. x .=? Just y = Just (x, toJSON y)
  113. _ .=? Nothing = Nothing
  114. infix 1 .=?
  115. (.=!) :: ToJSON a => Text -> [a] -> Maybe (Text, Value)
  116. _ .=! [] = Nothing
  117. x .=! ys = Just (x, toJSON ys)
  118. infix 1 .=!
  119. emptyObject :: Object objType
  120. emptyObject = Object
  121. { _oAttachments = []
  122. , _oAuthor = Nothing
  123. , _oContent = Nothing
  124. , _oDisplayName = Nothing
  125. , _oDownstreamDuplicates = []
  126. , _oId = Nothing
  127. , _oImage = Nothing
  128. , _oObjectType = Nothing
  129. , _oPublished = Nothing
  130. , _oSummary = Nothing
  131. , _oUpdated = Nothing
  132. , _oUpstreamDuplicates = []
  133. , _oURL = Nothing
  134. , _oRest = []
  135. }
  136. data Activity verb objType = Activity
  137. { _acActor :: Object objType
  138. , _acContent :: Maybe Text
  139. , _acGenerator :: Maybe (Object objType)
  140. , _acIcon :: Maybe MediaLink
  141. , _acId :: Maybe URI
  142. , _acPublished :: DateTime
  143. , _acProvider :: Object objType
  144. , _acTarget :: Maybe (Object objType)
  145. , _acTitle :: Maybe Text
  146. , _acUpdated :: Maybe DateTime
  147. , _acURL :: Maybe URI
  148. , _acVerb :: Maybe verb
  149. } deriving (Eq, Show)
  150. makeLenses ''Activity
  151. deriveJSON (commonOpts "_ac") ''Activity
  152. makeMinimalActivity :: Object objType -> DateTime -> Object objType
  153. -> Activity verb objType
  154. makeMinimalActivity actor published provider = Activity
  155. { _acActor = actor
  156. , _acContent = Nothing
  157. , _acGenerator = Nothing
  158. , _acIcon = Nothing
  159. , _acId = Nothing
  160. , _acPublished = published
  161. , _acProvider = provider
  162. , _acTarget = Nothing
  163. , _acTitle = Nothing
  164. , _acUpdated = Nothing
  165. , _acURL = Nothing
  166. , _acVerb = Nothing
  167. }
  168. data Collection objType = Collection
  169. { _cTotalItems :: Maybe Int
  170. , _cItems :: [Object objType]
  171. , _cURL :: Maybe URI
  172. } deriving (Eq, Show)
  173. makeLenses ''Collection
  174. deriveJSON (commonOpts "_c") ''Collection
  175. makeCollection :: [Object objType] -> Maybe URI -> Collection objType
  176. makeCollection objs url = Collection
  177. { _cTotalItems = Just (length objs)
  178. , _cItems = objs
  179. , _cURL = url
  180. }