Representation.hs 5.9 KB

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