gdritter repos activitystreams-aeson / f67a82a
Ticked version; removed non-Dynamic version of library Getty Ritter 9 years ago
6 changed file(s) with 898 addition(s) and 701 deletion(s). Collapse all Expand all
+0
-405
Codec/ActivityStream/DynamicSchema.hs less more
1 {-# LANGUAGE Rank2Types #-}
2 {-# LANGUAGE OverloadedStrings #-}
3
4 {-|
5 Module : Codec.ActivityStream.DynamicSchema
6 Description : A (more dynamic) interface to the Activity Streams Base Schema
7 Copyright : (c) Getty Ritter, 2014
8 Maintainer : gdritter@galois.com
9
10 This is an interface to the extended ActivityStreams schema which defines
11 an extensive set of @verb@ values, additional @objectType@ values, and a
12 set of extended properties for 'Object's.
13
14 Most of the inline documentation is drawn directly from the
15 <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md Activity Base Schema draft>
16 specification, with minor modifications
17 to refer to the corresponding data types in this module and to clarify
18 certain aspects. This is not an approved draft, and as such may be
19 subject to changes which will be reflected in this module. In contrast to
20 "Codec.ActivityStream", the API in this module makes __no guarantees about
21 long-term stability__.
22 -}
23
24 module Codec.ActivityStream.DynamicSchema
25 ( module Codec.ActivityStream.Dynamic
26 -- * Verbs
27 , SchemaVerb(..)
28 -- * Object Types
29 , SchemaObjectType(..)
30 -- ** Audio/Video
31 , avEmbedCode
32 , avStream
33 -- ** Binary
34 , bnCompression
35 , bnData
36 , bnFileUrl
37 , bnLength
38 , bnMd5
39 , bnMimeType
40 -- ** Event
41 , evAttendedBy
42 , evAttending
43 , evEndTime
44 , evInvited
45 , evMaybeAttending
46 , evNotAttendedBy
47 , evNotAttending
48 , evStartTime
49 -- ** Issue
50 , isTypes
51 -- ** Permission
52 , pmScope
53 , pmActions
54 -- ** Place
55 , plPosition
56 , plAddress
57 -- *** PlacePosition
58 , PlacePosition
59 -- *** PlaceAddress
60 , PlaceAddress
61 -- ** Role/Group
62 , rlMembers
63 -- ** Task
64 , tsActor
65 , tsBy
66 , tsObject
67 , tsPrerequisites
68 , tsRequired
69 , tsSupersedes
70 , tsVerb
71 -- * Basic Extension Properties
72 , acContext
73 , getLocation
74 , oMood
75 , oRating
76 , acResult
77 , getSource
78 , getStartTime
79 , getEndTime
80 , oTags
81 -- * Mood
82 , Mood
83 , moodRest
84 , moodDisplayName
85 , moodImage
86 ) where
87
88 import qualified Data.Aeson as Aeson
89 import Data.DateTime (DateTime)
90 import Data.Aeson ( FromJSON(..), ToJSON(..) )
91 import qualified Data.HashMap.Strict as HM
92 import Data.Text (Text)
93
94 import Codec.ActivityStream.LensInternal
95 import Codec.ActivityStream.Dynamic
96 import Codec.ActivityStream.Schema (SchemaVerb(..), SchemaObjectType(..))
97
98 -- audio/video
99
100 -- | A fragment of HTML markup that, when embedded within another HTML
101 -- page, provides an interactive user-interface for viewing or listening
102 -- to the video or audio stream.
103 avEmbedCode :: Lens' Object (Maybe Text)
104 avEmbedCode = makeAesonLensMb "embedCode" oRest
105
106 -- | An Activity Streams Media Link to the video or audio content itself.
107 avStream :: Lens' Object (Maybe MediaLink)
108 avStream = makeAesonLensMb "stream" oRest
109
110 -- binary
111
112 -- | An optional token identifying a compression algorithm applied to
113 -- the binary data prior to Base64-encoding. Possible algorithms
114 -- are "deflate" and "gzip", respectively indicating the use of
115 -- the compression mechanisms defined by RFC 1951 and RFC 1952.
116 -- Additional compression algorithms MAY be used but are not defined
117 -- by this specification. Note that previous versions of this
118 -- specification allowed for multiple compression algorithms to be
119 -- applied and listed using a comma-separated format. The use of
120 -- multiple compressions is no longer permitted.
121 bnCompression :: Lens' Object (Maybe Text)
122 bnCompression = makeAesonLensMb "compression" oRest
123
124 -- | The URL-Safe Base64-encoded representation of the binary data
125 bnData :: Lens' Object (Maybe Text)
126 bnData = makeAesonLensMb "data" oRest
127 -- | An optional IRI for the binary data described by this object.
128 bnFileUrl :: Lens' Object (Maybe Text)
129 bnFileUrl = makeAesonLensMb "fileUrl" oRest
130
131 -- | The total number of unencoded, uncompressed octets contained
132 -- within the "data" field.
133 bnLength :: Lens' Object (Maybe Text)
134 bnLength = makeAesonLensMb "length" oRest
135
136 -- | An optional MD5 checksum calculated over the unencoded,
137 -- uncompressed octets contained within the "data" field
138 bnMd5 :: Lens' Object (Maybe Text)
139 bnMd5 = makeAesonLensMb "md5" oRest
140
141 -- | The MIME Media Type of the binary data contained within the object.
142 bnMimeType :: Lens' Object (Maybe Text)
143 bnMimeType = makeAesonLensMb "mimeType" oRest
144
145 -- event
146
147 -- | A collection object as defined in Section 3.5 of the JSON
148 -- Activity Streams specification that provides information about
149 -- entities that attended the event.
150 evAttendedBy :: Lens' Object (Maybe Collection)
151 evAttendedBy = makeAesonLensMb "attendedBy" oRest
152
153 -- | A collection object as defined in Section 3.5 of the JSON
154 -- Activity Streams specification that provides information about
155 -- entities that intend to attend the event.
156 evAttending :: Lens' Object (Maybe Collection)
157 evAttending = makeAesonLensMb "attending" oRest
158
159 -- | The date and time that the event ends represented as a String
160 -- conforming to the "date-time" production in [RFC3339].
161 evEndTime :: Lens' Object (Maybe DateTime)
162 evEndTime = makeAesonLensMb "endTime" oRest
163
164 -- | A collection object as defined in Section 3.5 of the JSON
165 -- Activity Streams specification that provides information about
166 -- entities that have been invited to the event.
167 evInvited :: Lens' Object (Maybe Collection)
168 evInvited = makeAesonLensMb "invited" oRest
169
170 -- | A collection object as defined in Section 3.5 of the JSON
171 -- Activity Streams specification that provides information about
172 -- entities that possibly may attend the event.
173 evMaybeAttending :: Lens' Object (Maybe Collection)
174 evMaybeAttending = makeAesonLensMb "maybeAttending" oRest
175
176 -- | A collection object as defined in Section 3.5 of the JSON
177 -- Activity Streams specification that provides information about
178 -- entities that did not attend the event.
179 evNotAttendedBy :: Lens' Object (Maybe Collection)
180 evNotAttendedBy = makeAesonLensMb "notAttendedBy" oRest
181
182 -- | A collection object as defined in Section 3.5 of the JSON
183 -- Activity Streams specification that provides information about
184 -- entities that do not intend to attend the event.
185 evNotAttending :: Lens' Object (Maybe Collection)
186 evNotAttending = makeAesonLensMb "notAttending" oRest
187
188 -- | The date and time that the event begins represented as a String
189 -- confirming to the "date-time" production in RFC 3339.
190 evStartTime :: Lens' Object (Maybe DateTime)
191 evStartTime = makeAesonLensMb "startTime" oRest
192
193 -- issue
194
195 -- | An array of one or more absolute IRI's that describe the type of
196 -- issue represented by the object. Note that the IRI's are intended
197 -- for use as identifiers and MAY or MAY NOT be dereferenceable.
198 isTypes :: Lens' Object (Maybe [Text])
199 isTypes = makeAesonLensMb "types" oRest
200
201 -- permission
202
203 -- | A single Activity Streams Object, of any objectType, that
204 -- identifies the scope of the permission. For example, if the
205 -- permission objects describes write permissions for a given file,
206 -- the scope property would be a file object describing that file.
207 pmScope :: Lens' Object (Maybe Object)
208 pmScope = makeAesonLensMb "scope" oRest
209
210 -- | An array of Strings that identify the specific actions associated
211 -- with the permission. The actions are application and scope
212 -- specific. No common, core set of actions is defined by this
213 -- specification.
214 pmActions :: Lens' Object (Maybe [Text])
215 pmActions = makeAesonLensMb "actions" oRest
216
217 -- place
218
219 -- | The latitude, longitude and altitude of the place as a point on
220 -- Earth. Represented as a JSON Object as described below.
221 plPosition :: Lens' Object (Maybe PlacePosition)
222 plPosition = makeAesonLensMb "position" oRest
223
224 -- | A physical address represented as a JSON object as described below.
225 plAddress :: Lens' Object (Maybe PlaceAddress)
226 plAddress = makeAesonLensMb "address" oRest
227
228 data PlacePosition = PPO { fromPPO :: Aeson.Object } deriving (Eq, Show)
229
230 instance FromJSON PlacePosition where
231 parseJSON (Aeson.Object o)
232 | HM.member "altitude" o
233 && HM.member "latitude" o
234 && HM.member "longitude" o = return (PPO o)
235 | otherwise = fail "..."
236 parseJSON _ = fail "..."
237
238 instance ToJSON PlacePosition where
239 toJSON = Aeson.Object . fromPPO
240
241 data PlaceAddress = PAO { fromPAO :: Aeson.Object } deriving (Eq, Show)
242
243 instance FromJSON PlaceAddress where
244 parseJSON (Aeson.Object o)
245 | HM.member "formatted" o
246 && HM.member "streetAddress" o
247 && HM.member "locality" o
248 && HM.member "region" o
249 && HM.member "postalCode" o
250 && HM.member "country" o = return (PAO o)
251 | otherwise = fail "..."
252 parseJSON _ = fail "..."
253
254 instance ToJSON PlaceAddress where
255 toJSON = Aeson.Object . fromPAO
256
257 -- role/group
258
259 -- | An optional Activity Streams Collection object listing the
260 -- members of a group, or listing the entities assigned to a
261 -- particular role.
262 rlMembers :: Lens' Object (Maybe [Object])
263 rlMembers = makeAesonLensMb "members" oRest
264
265 -- Task
266
267 -- | An Activity Streams Object that provides information about the
268 -- actor that is expected to complete the task.
269 tsActor :: Lens' Object (Maybe Object)
270 tsActor = makeAesonLensMb "actor" oRest
271
272 -- | A RFC 3339 date-time specifying the date and time by which the
273 -- task is to be completed.
274 tsBy :: Lens' Object (Maybe DateTime)
275 tsBy = makeAesonLensMb "by" oRest
276
277 -- | An Activity Streams object describing the object of the task.
278 tsObject :: Lens' Object (Maybe Object)
279 tsObject = makeAesonLensMb "object" oRest
280
281 -- | An Array of other Task objects that are to be completed before
282 -- this task can be completed.
283 tsPrerequisites :: Lens' Object (Maybe [Object])
284 tsPrerequisites = makeAesonLensMb "prerequisites" oRest
285
286 -- | A boolean value indicating whether completion of this task is
287 -- considered to be mandatory.
288 tsRequired :: Lens' Object (Maybe Bool)
289 tsRequired = makeAesonLensMb "required" oRest
290
291 -- | An Array of other Task objects that are superseded by this task object.
292 tsSupersedes :: Lens' Object (Maybe [Object])
293 tsSupersedes = makeAesonLensMb "supersedes" oRest
294
295 -- | A string indicating the verb for this task as defined in Section
296 -- 3.2 of [activitystreams].
297 tsVerb :: Lens' Object (Maybe SchemaVerb)
298 tsVerb = makeAesonLensMb "verb" oRest
299
300 -- extra properties
301
302 -- | The additional @context@ property allows an 'Activity' to further
303 -- include information about why a particular action occurred by
304 -- providing details about the context within which a particular
305 -- Activity was performed. The value of the @context@ property is an
306 -- 'Object' of any @objectType@. The meaning of the @context@ property is
307 -- only defined when used within an 'Activity' object.
308 acContext :: Lens' Activity (Maybe Object)
309 acContext = makeAesonLensMb "context" acRest
310
311 -- | When appearing within an activity, the location data indicates
312 -- the location where the activity occurred. When appearing within an
313 -- object, the location data indicates the location of that object at
314 -- the time the activity occurred.
315 getLocation :: Lens' a Aeson.Object -> Lens' a (Maybe Object)
316 getLocation = makeAesonLensMb "location"
317
318 -- | Mood describes the mood of the user when the activity was
319 -- performed. This is usually collected via an extra field in the user
320 -- interface used to perform the activity. For the purpose of the
321 -- schema, a mood is a freeform, short mood keyword or phrase along
322 -- with an optional mood icon image.
323 oMood :: Lens' Object (Maybe Mood)
324 oMood = makeAesonLensMb "mood" oRest
325
326 -- | A rating given as a number between 1.0 and 5.0 inclusive with one
327 -- decimal place of precision. Represented in JSON as a property
328 -- called @rating@ whose value is a JSON number giving the rating.
329 oRating :: Lens' Object (Maybe Double)
330 oRating = makeAesonLensMb "rating" oRest
331
332 -- | The @result@ provides a description of the result of any particular
333 -- activity. The value of the @result@ property is an Object of any
334 -- objectType. The meaning of the @result@ property is only defined when
335 -- used within an 'Activity' object.
336 acResult :: Lens' Activity (Maybe Object)
337 acResult = makeAesonLensMb "result" acRest
338
339 -- | The @source@ property provides a reference to the original source of
340 -- an object or activity. The value of the @source@ property is an
341 -- Object of any objectType.
342 --
343 -- The @source@ property is closely related to
344 -- the @generator@ and @provider@ properties but serves the distinct
345 -- purpose of identifying where the activity or object was originally
346 -- published as opposed to identifying the applications that generated
347 -- or published it.
348 getSource :: Lens' a Aeson.Object -> Lens' a (Maybe Object)
349 getSource = makeAesonLensMb "source"
350
351 -- | When an long running Activity occurs over a distinct period of
352 -- time, or when an Object represents a long-running process or event,
353 -- the @startTime@ propertiy can be used to specify the
354 -- date and time at which the activity or object begins.
355 -- The values for each are represented as JSON Strings
356 -- conforming to the "date-time" production in RFC3339.
357 getStartTime :: Lens' a Aeson.Object -> Lens' a (Maybe Text)
358 getStartTime = makeAesonLensMb "startTime"
359
360 -- | When an long running Activity occurs over a distinct period of
361 -- time, or when an Object represents a long-running process or event,
362 -- the @endTime@ propertiy can be used to specify the
363 -- date and time at which the activity or object concludes.
364 -- The values for each are represented as JSON Strings
365 -- conforming to the "date-time" production in RFC3339.
366 getEndTime :: Lens' a Aeson.Object -> Lens' a (Maybe Text)
367 getEndTime = makeAesonLensMb "endTime"
368
369 -- | A listing of the objects that have been associated with a
370 -- particular object. Represented in JSON using a property named @tags@
371 -- whose value is an Array of objects.
372 oTags :: Lens' Object (Maybe [Object])
373 oTags = makeAesonLensMb "tags" oRest
374
375 -- mood
376
377 -- | Mood describes the mood of the user when the activity was
378 -- performed. This is usually collected via an extra field in the user
379 -- interface used to perform the activity. For the purpose of this
380 -- schema, a mood is a freeform, short mood keyword or phrase along
381 -- with an optional mood icon image.
382 data Mood = Mood { fromMood :: Aeson.Object } deriving (Eq, Show)
383
384 instance FromJSON Mood where
385 parseJSON (Aeson.Object o)
386 | HM.member "displayName" o
387 && HM.member "image" o = return (Mood o)
388 | otherwise = fail "..."
389 parseJSON _ = fail "..."
390
391 instance ToJSON Mood where
392 toJSON = Aeson.Object . fromMood
393
394 -- | Access to the underlying JSON object of a 'Mood'
395 moodRest :: Lens' Mood Aeson.Object
396 moodRest = makeLens fromMood (\ o' m -> m { fromMood = o' })
397
398 -- | The natural-language, human-readable and plain-text keyword or
399 -- phrase describing the mood. HTML markup MUST NOT be included.
400 moodDisplayName :: Lens' Mood Text
401 moodDisplayName = makeAesonLens "displayName" moodRest
402
403 -- | An optional image that provides a visual representation of the mood.
404 moodImage :: Lens' Mood MediaLink
405 moodImage = makeAesonLens "image" moodRest
11 {-# LANGUAGE ViewPatterns #-}
22
3 module Codec.ActivityStream.Internal (commonOpts, commonOptsCC) where
3 module Codec.ActivityStream.Internal (commonOpts, commonOptsCC, ensure) where
44
55 import Control.Monad (mzero)
66 import Data.Aeson
77 import Data.Aeson.TH
88 import Data.Char
9 import Data.Text (pack, unpack)
10 import Network.URI (URI, parseURI)
9 import Data.HashMap.Strict (HashMap, member)
10 import Data.Monoid ((<>))
11 import Data.Text (Text, pack, unpack)
1112
12 instance FromJSON URI where
13 parseJSON (String ((parseURI . unpack) -> Just u)) = return u
14 parseJSON _ = mzero
15
16 instance ToJSON URI where
17 toJSON = String . pack . show
13 ensure :: Monad m => String -> HashMap Text Value -> [Text] -> m ()
14 ensure objName obj keys = mapM_ go keys
15 where go k
16 | member k obj = return ()
17 | otherwise = fail ("Object \"" <> objName <>
18 "\" does not contain property \"" <>
19 unpack k <> "\"")
1820
1921 toCamelCaseUpper :: String -> String
2022 toCamelCaseUpper = toCamelCase True
5052 { fieldLabelModifier = fromCamelCase . drop (length prefix)
5153 , constructorTagModifier = fromCamelCase
5254 , omitNothingFields = True
55
5356 }
11 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE TemplateHaskell #-}
3
4 module Codec.ActivityStream.Representation where
5
6 import Control.Applicative
7 import Control.Lens hiding ((.=))
2
3
4 {-|
5 Module : Codec.ActivityStream.Representation
6 Description : A (more dynamic) interface to Activity Streams
7 Copyright : (c) Getty Ritter, 2014
8 Maintainer : gdritter@galois.com
9
10 This is an interface to ActivityStreams that simply wraps an underlying
11 @aeson@ Object, and exposes a set of (convenient) lenses to access the
12 values inside. If an @aeson@ object is wrapped in the respective wrapper,
13 it will contain the obligatory values for that type (e.g. an 'Activity'
14 is guaranteed to have a @published@ date.)
15
16 Most of the inline documentation is drawn directly from the
17 <http://activitystrea.ms/specs/json/1.0/ JSON Activity Streams 1.0>
18 specification, with minor modifications
19 to refer to the corresponding data types in this module and to clarify
20 certain aspects.
21 -}
22
23 module Codec.ActivityStream.Representation
24 ( Lens'
25 -- * Object
26 , Object
27 , emptyObject
28 -- ** Object Lenses
29 , oAttachments
30 , oAuthor
31 , oContent
32 , oDisplayName
33 , oDownstreamDuplicates
34 , oId
35 , oImage
36 , oObjectType
37 , oPublished
38 , oSummary
39 , oUpdated
40 , oUpstreamDuplicates
41 , oURL
42 , oRest
43 -- * Activity
44 , Activity
45 , makeActivity
46 , asObject
47 -- ** Activity Lenses
48 , acActor
49 , acContent
50 , acGenerator
51 , acIcon
52 , acId
53 , acObject
54 , acPublished
55 , acProvider
56 , acTarget
57 , acTitle
58 , acUpdated
59 , acURL
60 , acVerb
61 , acRest
62 -- * MediaLink
63 , MediaLink
64 , makeMediaLink
65 -- ** MediaLink Lenses
66 , mlDuration
67 , mlHeight
68 , mlWidth
69 , mlURL
70 , mlRest
71 -- * Collection
72 , Collection
73 , makeCollection
74 -- ** Collection Lenses
75 , cTotalItems
76 , cItems
77 , cURL
78 , cRest
79 ) where
80
881 import Data.Aeson ( FromJSON(..)
982 , ToJSON(..)
10 , Value
83 , Result(..)
1184 , fromJSON
12 , object
13 , (.=)
14 , (.:)
15 , (.:?)
1685 )
17 import qualified Data.Aeson as Ae
18 import Data.Aeson.TH
19 import Data.DateTime
86 import qualified Data.Aeson as A
87 import Data.DateTime (DateTime)
2088 import qualified Data.HashMap.Strict as HM
21 import Data.Maybe (catMaybes)
2289 import Data.Text (Text)
23 import Network.URI
24
25 import Codec.ActivityStream.Internal
26
27 data Verb ext
28 = Post
29 | VerbExt ext
30 deriving (Eq, Show)
31
32 instance FromJSON ext => FromJSON (Verb ext) where
33 parseJSON (Ae.String "post") = return Post
34 parseJSON ext = VerbExt `fmap` parseJSON ext
35
36 instance ToJSON ext => ToJSON (Verb ext) where
37 toJSON Post = Ae.String "post"
38 toJSON (VerbExt ext) = toJSON ext
39
40 data MediaLink = MediaLink
41 { _mlDuration :: Maybe Int
42 , _mlHeight :: Maybe Int
43 , _mlURL :: Text
44 , _mlWidth :: Maybe Int
45 } deriving (Eq, Show)
46
47 makeLenses ''MediaLink
48 deriveJSON (commonOpts "_ml") ''MediaLink
49
50 data Object objType = Object
51 { _oAttachments :: [Object objType]
52 , _oAuthor :: Maybe (Object objType)
53 , _oContent :: Maybe Text
54 , _oDisplayName :: Maybe Text
55 , _oDownstreamDuplicates :: [URI]
56 , _oId :: Maybe URI
57 , _oImage :: Maybe MediaLink
58 , _oObjectType :: Maybe objType
59 , _oPublished :: Maybe DateTime
60 , _oSummary :: Maybe Text
61 , _oUpdated :: Maybe DateTime
62 , _oUpstreamDuplicates :: [URI]
63 , _oURL :: Maybe URI
64 , _oRest :: [(Text, Value)]
65 } deriving (Eq, Show)
66
67 makeLenses ''Object
68
69 objectFields :: [Text]
70 objectFields =
71 [ "attachments"
72 , "author"
73 , "content"
74 , "displayName"
75 , "downstreamDuplicates"
76 , "id"
77 , "image"
78 , "objectType"
79 , "published"
80 , "summary"
81 , "updated"
82 , "upstreamDuplicates"
83 , "url"
84 ]
85
86 instance FromJSON objType => FromJSON (Object objType) where
87 parseJSON (Ae.Object o) =
88 Object <$> fmap go (o .:? "attachments")
89 <*> o .:? "author"
90 <*> o .:? "content"
91 <*> o .:? "displayName"
92 <*> fmap go (o .:? "downstreamDuplicates")
93 <*> o .:? "id"
94 <*> o .:? "image"
95 <*> o .:? "objectType"
96 <*> o .:? "published"
97 <*> o .:? "summary"
98 <*> o .:? "updated"
99 <*> fmap go (o .:? "upstreamDuplicates")
100 <*> o .:? "url"
101 <*> pure rest
102 where rest = HM.toList (foldr HM.delete o objectFields)
103 go :: Maybe [a] -> [a]
104 go Nothing = []
105 go (Just xs) = xs
106
107 instance ToJSON objType => ToJSON (Object objType) where
108 toJSON obj = object (attrs ++ _oRest obj)
109 where attrs = catMaybes
110 [ "attachments" .=! _oAttachments obj
111 , "author" .=? _oAuthor obj
112 , "content" .=? _oContent obj
113 , "displayName" .=? _oDisplayName obj
114 , "downstreamDuplicates" .=! _oDownstreamDuplicates obj
115 , "id" .=? _oId obj
116 , "image" .=? _oImage obj
117 , "objectType" .=? _oObjectType obj
118 , "published" .=? _oPublished obj
119 , "summary" .=? _oSummary obj
120 , "updated" .=? _oUpdated obj
121 , "upstreamDuplicates" .=! _oUpstreamDuplicates obj
122 , "url" .=? _oURL obj
123 ]
124 (.=?) :: ToJSON a => Text -> Maybe a -> Maybe (Text, Value)
125 x .=? Just y = Just (x, toJSON y)
126 _ .=? Nothing = Nothing
127 infix 1 .=?
128 (.=!) :: ToJSON a => Text -> [a] -> Maybe (Text, Value)
129 _ .=! [] = Nothing
130 x .=! ys = Just (x, toJSON ys)
131 infix 1 .=!
132
133 emptyObject :: Object objType
134 emptyObject = Object
135 { _oAttachments = []
136 , _oAuthor = Nothing
137 , _oContent = Nothing
138 , _oDisplayName = Nothing
139 , _oDownstreamDuplicates = []
140 , _oId = Nothing
141 , _oImage = Nothing
142 , _oObjectType = Nothing
143 , _oPublished = Nothing
144 , _oSummary = Nothing
145 , _oUpdated = Nothing
146 , _oUpstreamDuplicates = []
147 , _oURL = Nothing
148 , _oRest = []
149 }
150
151 data Activity verb objType = Activity
152 { _acActor :: Object objType
153 , _acContent :: Maybe Text
154 , _acGenerator :: Maybe (Object objType)
155 , _acIcon :: Maybe MediaLink
156 , _acId :: Maybe URI
157 , _acPublished :: DateTime
158 , _acProvider :: Object objType
159 , _acTarget :: Maybe (Object objType)
160 , _acTitle :: Maybe Text
161 , _acUpdated :: Maybe DateTime
162 , _acURL :: Maybe URI
163 , _acVerb :: Maybe verb
164 } deriving (Eq, Show)
165
166 makeLenses ''Activity
167 deriveJSON (commonOpts "_ac") ''Activity
168
169 makeMinimalActivity :: Object objType -> DateTime -> Object objType
170 -> Activity verb objType
171 makeMinimalActivity actor published provider = Activity
172 { _acActor = actor
173 , _acContent = Nothing
174 , _acGenerator = Nothing
175 , _acIcon = Nothing
176 , _acId = Nothing
177 , _acPublished = published
178 , _acProvider = provider
179 , _acTarget = Nothing
180 , _acTitle = Nothing
181 , _acUpdated = Nothing
182 , _acURL = Nothing
183 , _acVerb = Nothing
184 }
185
186 data Collection objType = Collection
187 { _cTotalItems :: Maybe Int
188 , _cItems :: [Object objType]
189 , _cURL :: Maybe URI
190 } deriving (Eq, Show)
191
192 makeLenses ''Collection
193 deriveJSON (commonOpts "_c") ''Collection
194
195 makeCollection :: [Object objType] -> Maybe URI -> Collection objType
90
91 import Codec.ActivityStream.Internal (ensure)
92 import Codec.ActivityStream.LensInternal
93
94 -- | Some types of objects may have an alternative visual representation in
95 -- the form of an image, video or embedded HTML fragments. A 'MediaLink'
96 -- represents a hyperlink to such resources.
97 newtype MediaLink = MediaLink { fromMediaLink :: A.Object } deriving (Eq, Show)
98
99 instance FromJSON MediaLink where
100 parseJSON (A.Object o) = do
101 ensure "MediaLink" o ["url"]
102 return (MediaLink o)
103 parseJSON _ = fail "MediaLink not an object"
104
105 instance ToJSON MediaLink where
106 toJSON (MediaLink o) = A.Object o
107
108 -- | Access the underlying JSON object that represents a Media Link
109 mlRest :: Lens' MediaLink A.Object
110 mlRest = makeLens fromMediaLink (\ o' m -> m { fromMediaLink = o' })
111
112 -- | A hint to the consumer about the length, in seconds, of the media
113 -- resource identified by the url property. A media link MAY contain
114 -- a "duration" property when the target resource is a time-based
115 -- media item such as an audio or video.
116 mlDuration :: Lens' MediaLink (Maybe Int)
117 mlDuration = makeAesonLensMb "duration" mlRest
118
119 -- | A hint to the consumer about the height, in pixels, of the media
120 -- resource identified by the url property. A media link MAY contain
121 -- a @height@ property when the target resource is a visual media item
122 -- such as an image, video or embeddable HTML page.
123 mlHeight :: Lens' MediaLink (Maybe Int)
124 mlHeight = makeAesonLensMb "height" mlRest
125
126 -- | A hint to the consumer about the width, in pixels, of the media
127 -- resource identified by the url property. A media link MAY contain
128 -- a @width@ property when the target resource is a visual media item
129 -- such as an image, video or embeddable HTML page.
130 mlWidth :: Lens' MediaLink (Maybe Int)
131 mlWidth = makeAesonLensMb "width" mlRest
132
133 -- | The IRI of the media resource being linked. A media link MUST have a
134 -- @url@ property.
135 mlURL :: Lens' MediaLink Text
136 mlURL = makeAesonLens "url" mlRest
137
138 -- | Create a @MediaLink@ with just a @url@ property, and all other
139 -- properties undefined.
140 makeMediaLink :: Text -> MediaLink
141 makeMediaLink url = MediaLink (HM.insert "url" (toJSON url) HM.empty)
142
143 -- | Within the specification, an 'Object' is a thing, real or
144 -- imaginary, which participates in an activity. It may be the
145 -- entity performing the activity, or the entity on which the
146 -- activity was performed. An object consists of properties
147 -- defined below. Certain object types may
148 -- further refine the meaning of these properties, or they may
149 -- define additional properties.
150 --
151 -- To maintain this flexibility in the Haskell environment, an
152 -- 'Object' is an opaque wrapper over an underlying JSON value,
153 -- and the 'oRest' accessor can be used to access that underlying
154 -- value.
155
156 newtype Object = Object { fromObject :: A.Object } deriving (Eq, Show)
157
158 instance FromJSON Object where
159 parseJSON (A.Object o) = return (Object o)
160 parseJSON _ = fail "Object not an object"
161
162 instance ToJSON Object where
163 toJSON (Object o) = A.Object o
164
165 -- | Access the underlying JSON object that represents an 'Object'
166 oRest :: Lens' Object A.Object
167 oRest = makeLens fromObject (\ o' m -> m { fromObject = o' })
168
169 -- | A collection of one or more additional, associated objects, similar
170 -- to the concept of attached files in an email message. An object MAY
171 -- have an attachments property whose value is a JSON Array of 'Object's.
172 oAttachments :: Lens' Object (Maybe [Object])
173 oAttachments = makeAesonLensMb "attachments" oRest
174
175 -- | Describes the entity that created or authored the object. An object
176 -- MAY contain a single author property whose value is an 'Object' of any
177 -- type. Note that the author field identifies the entity that created
178 -- the object and does not necessarily identify the entity that
179 -- published the object. For instance, it may be the case that an
180 -- object created by one person is posted and published to a system by
181 -- an entirely different entity.
182 oAuthor :: Lens' Object (Maybe Object)
183 oAuthor = makeAesonLensMb "author" oRest
184
185 -- | Natural-language description of the object encoded as a single JSON
186 -- String containing HTML markup. Visual elements such as thumbnail
187 -- images MAY be included. An object MAY contain a @content@ property.
188 oContent :: Lens' Object (Maybe Text)
189 oContent = makeAesonLensMb "content" oRest
190
191 -- | A natural-language, human-readable and plain-text name for the
192 -- object. HTML markup MUST NOT be included. An object MAY contain
193 -- a @displayName@ property. If the object does not specify an @objectType@
194 -- property, the object SHOULD specify a @displayName@.
195 oDisplayName :: Lens' Object (Maybe Text)
196 oDisplayName = makeAesonLensMb "displayName" oRest
197
198 -- | A JSON Array of one or more absolute IRI's
199 -- <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]> identifying
200 -- objects that duplicate this object's content. An object SHOULD
201 -- contain a @downstreamDuplicates@ property when there are known objects,
202 -- possibly in a different system, that duplicate the content in this
203 -- object. This MAY be used as a hint for consumers to use when
204 -- resolving duplicates between objects received from different sources.
205 oDownstreamDuplicates :: Lens' Object (Maybe [Text])
206 oDownstreamDuplicates = makeAesonLensMb "downstreamDuplicates" oRest
207
208 -- | Provides a permanent, universally unique identifier for the object in
209 -- the form of an absolute IRI
210 -- <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>. An
211 -- object SHOULD contain a single @id@ property. If an object does not
212 -- contain an @id@ property, consumers MAY use the value of the @url@
213 -- property as a less-reliable, non-unique identifier.
214
215 oId :: Lens' Object (Maybe Text)
216 oId = makeAesonLensMb "id" oRest
217
218 -- | Description of a resource providing a visual representation of the
219 -- object, intended for human consumption. An object MAY contain an
220 -- @image@ property whose value is a 'MediaLink'.
221 oImage :: Lens' Object (Maybe MediaLink)
222 oImage = makeAesonLensMb "image" oRest
223
224 -- | Identifies the type of object. An object MAY contain an @objectType@
225 -- property whose value is a JSON String that is non-empty and matches
226 -- either the "isegment-nz-nc" or the \"IRI\" production in
227 -- <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>. Note
228 -- that the use of a relative reference other than a simple name is
229 -- not allowed. If no @objectType@ property is contained, the object has
230 -- no specific type.
231 oObjectType :: (FromJSON o, ToJSON o) => Lens' Object (Maybe o)
232 oObjectType = makeAesonLensMb "objectType" oRest
233
234 -- | The date and time at which the object was published. An object MAY
235 -- contain a @published@ property.
236 oPublished :: Lens' Object (Maybe DateTime)
237 oPublished = makeAesonLensMb "published" oRest
238
239 -- | Natural-language summarization of the object encoded as a single
240 -- JSON String containing HTML markup. Visual elements such as thumbnail
241 -- images MAY be included. An activity MAY contain a @summary@ property.
242 oSummary :: Lens' Object (Maybe Text)
243 oSummary = makeAesonLensMb "summary" oRest
244
245 -- | The date and time at which a previously published object has been
246 -- modified. An Object MAY contain an @updated@ property.
247 oUpdated :: Lens' Object (Maybe DateTime)
248 oUpdated = makeAesonLensMb "updated" oRest
249
250 -- | A JSON Array of one or more absolute IRI's
251 -- <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]> identifying
252 -- objects that duplicate this object's content. An object SHOULD contain
253 -- an @upstreamDuplicates@ property when a publisher is knowingly
254 -- duplicating with a new ID the content from another object. This MAY be
255 -- used as a hint for consumers to use when resolving duplicates between
256 -- objects received from different sources.
257 oUpstreamDuplicates :: Lens' Object (Maybe [Text])
258 oUpstreamDuplicates = makeAesonLensMb "upstreamDuplicates" oRest
259
260 -- | An IRI <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>
261 -- identifying a resource providing an HTML representation of the
262 -- object. An object MAY contain a url property
263 oURL :: Lens' Object (Maybe Text)
264 oURL = makeAesonLensMb "url" oRest
265
266 -- | Create an @Object@ with no fields.
267 emptyObject :: Object
268 emptyObject = Object HM.empty
269
270 -- | In its simplest form, an 'Activity' consists of an @actor@, a @verb@, an
271 -- @object@, and a @target@. It tells the story of a person performing an
272 -- action on or with an object -- "Geraldine posted a photo to her
273 -- album" or "John shared a video". In most cases these components
274 -- will be explicit, but they may also be implied.
275
276 newtype Activity = Activity { fromActivity :: A.Object } deriving (Eq, Show)
277
278 instance FromJSON Activity where
279 parseJSON (A.Object o) = do
280 ensure "Activity" o ["published", "provider"]
281 return (Activity o)
282 parseJSON _ = fail "\"Activity\" not an object"
283
284 instance ToJSON Activity where
285 toJSON (Activity o) = A.Object o
286
287 -- | Access the underlying JSON object that represents an 'Activity'
288 acRest :: Lens' Activity A.Object
289 acRest = makeLens fromActivity (\ o' m -> m { fromActivity = o' })
290
291 -- | Describes the entity that performed the activity. An activity MUST
292 -- contain one @actor@ property whose value is a single 'Object'.
293 acActor :: Lens' Activity Object
294 acActor = makeAesonLens "actor" acRest
295
296 -- | Natural-language description of the activity encoded as a single
297 -- JSON String containing HTML markup. Visual elements such as
298 -- thumbnail images MAY be included. An activity MAY contain a
299 -- @content@ property.
300 acContent :: Lens' Activity (Maybe Text)
301 acContent = makeAesonLensMb "content" acRest
302
303 -- | Describes the application that generated the activity. An activity
304 -- MAY contain a @generator@ property whose value is a single 'Object'.
305 acGenerator :: Lens' Activity (Maybe Object)
306 acGenerator = makeAesonLens "generator" acRest
307
308 -- | Description of a resource providing a visual representation of the
309 -- object, intended for human consumption. The image SHOULD have an
310 -- aspect ratio of one (horizontal) to one (vertical) and SHOULD be
311 -- suitable for presentation at a small size. An activity MAY have
312 -- an @icon@ property.
313 acIcon :: Lens' Activity (Maybe MediaLink)
314 acIcon = makeAesonLensMb "icon" acRest
315
316 -- | Provides a permanent, universally unique identifier for the activity
317 -- in the form of an absolute IRI
318 -- <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>. An
319 -- activity SHOULD contain a single @id@ property. If an activity does
320 -- not contain an @id@ property, consumers MAY use the value of the
321 -- @url@ property as a less-reliable, non-unique identifier.
322 acId :: Lens' Activity (Maybe Text)
323 acId = makeAesonLensMb "id" acRest
324
325 -- | Describes the primary object of the activity. For instance, in the
326 -- activity, "John saved a movie to his wishlist", the object of the
327 -- activity is "movie". An activity SHOULD contain an @object@ property
328 -- whose value is a single 'Object'. If the @object@ property is not
329 -- contained, the primary object of the activity MAY be implied by
330 -- context.
331 acObject :: Lens' Activity (Maybe Object)
332 acObject = makeAesonLensMb "object" acRest
333
334 -- | The date and time at which the activity was published. An activity
335 -- MUST contain a @published@ property.
336 acPublished :: Lens' Activity DateTime
337 acPublished = makeAesonLens "published" acRest
338
339 -- | Describes the application that published the activity. Note that this
340 -- is not necessarily the same entity that generated the activity. An
341 -- activity MAY contain a @provider@ property whose value is a
342 -- single 'Object'.
343 acProvider :: Lens' Activity (Maybe Object)
344 acProvider = makeAesonLensMb "provider" acRest
345
346 -- | Describes the target of the activity. The precise meaning of the
347 -- activity's target is dependent on the activities verb, but will
348 -- often be the object the English preposition "to". For instance, in
349 -- the activity, "John saved a movie to his wishlist", the target of
350 -- the activity is "wishlist". The activity target MUST NOT be used
351 -- to identity an indirect object that is not a target of the
352 -- activity. An activity MAY contain a @target@ property whose value
353 -- is a single 'Object'.
354 acTarget :: Lens' Activity (Maybe Object)
355 acTarget = makeAesonLensMb "target" acRest
356
357 -- | Natural-language title or headline for the activity encoded as a
358 -- single JSON String containing HTML markup. An activity MAY contain
359 -- a @title@ property.
360 acTitle :: Lens' Activity (Maybe Text)
361 acTitle = makeAesonLensMb "title" acRest
362
363 -- | The date and time at which a previously published activity has
364 -- been modified. An Activity MAY contain an @updated@ property.
365 acUpdated :: Lens' Activity (Maybe DateTime)
366 acUpdated = makeAesonLensMb "updated" acRest
367
368 -- | An IRI <http://www.ietf.org/rfc/rfc3987.txt RFC3987>
369 -- identifying a resource providing an HTML representation of the
370 -- activity. An activity MAY contain a @url@ property.
371 acURL :: Lens' Activity (Maybe Text)
372 acURL = makeAesonLensMb "url" acRest
373
374 -- | Identifies the action that the activity describes. An activity SHOULD
375 -- contain a verb property whose value is a JSON String that is
376 -- non-empty and matches either the \"isegment-nz-nc\" or the
377 -- \"IRI\" production in <http://www.ietf.org/rfc/rfc3987.txt [RFC3987]>.
378 -- Note that the use of a relative
379 -- reference other than a simple name is not allowed. If the @verb@ is
380 -- not specified, or if the value is null, the @verb@ is
381 -- assumed to be \"post\".
382 acVerb :: (FromJSON v, ToJSON v) => Lens' Activity (Maybe v)
383 acVerb = makeAesonLensMb "verb" acRest
384
385 -- | Create an @Activity@ with an @actor@, @published@, and
386 -- @provider@ property.
387 makeActivity :: Object -> DateTime -> Activity
388 makeActivity actor published = Activity
389 $ HM.insert "actor" (toJSON actor)
390 $ HM.insert "published" (toJSON published)
391 $ HM.empty
392
393 -- | JSON Activity Streams 1.0 specificies that an @Activity@ may be used as an
394 -- @Object@. In such a case, the object may have fields permitted on either an
395 -- @Activity@ or an @Object@
396 asObject :: Activity -> Object
397 asObject act = Object (fromActivity act)
398
399 -- | A "collection" is a generic list of 'Object's of any object type.
400 -- The @objectType@ of each item in the collection MAY be omitted if
401 -- the type of object can be established through context. The collection
402 -- is used primarily as the root of an Activity Streams document as described
403 -- in Section 4,
404 -- but can be used as the value of extension properties in a variety of
405 -- situations.
406
407 newtype Collection = Collection { fromCollection :: A.Object } deriving (Eq, Show)
408
409 instance FromJSON Collection where
410 parseJSON (A.Object o) = return (Collection o)
411 parseJSON _ = fail "\"Collection\" not an object"
412
413 instance ToJSON Collection where
414 toJSON (Collection o) = A.Object o
415
416 -- | Access the underlying JSON object that represents a 'Collection'
417 cRest :: Lens' Collection A.Object
418 cRest = makeLens fromCollection (\ o' m -> m { fromCollection = o' })
419
420 -- | Non-negative integer specifying the total number of activities
421 -- within the stream. The Stream serialization MAY contain a
422 -- @totalItems@ property. (NOTE: there is a typo in the original
423 -- specification, in which it inconsistently refers to this as
424 -- either @totalItems@ or @count@.)
425 cTotalItems :: Lens' Collection (Maybe Int)
426 cTotalItems = makeAesonLensMb "totalItems" cRest
427
428 -- | An array containing a listing of 'Object's of any object type.
429 -- If used in combination with the @url@ property, the @items@ array
430 -- can be used to provide a subset of the objects that may be
431 -- found in the resource identified by the @url@.
432 cItems :: Lens' Collection (Maybe [Object])
433 cItems = makeAesonLensMb "items" cRest
434
435 -- | An IRI <http://activitystrea.ms/specs/json/1.0/#RFC3987 [RFC3987]>
436 -- referencing a JSON document containing the full
437 -- listing of objects in the collection.
438 cURL :: Lens' Collection (Maybe Text)
439 cURL = makeAesonLensMb "url" cRest
440
441 -- | Create a @Collection@ with an @items@ and a @url@ property
442 -- and fill in the corresponding @totalItems@ field with the
443 -- length of the @items@ array.
444 makeCollection :: [Object] -> Text -> Collection
196445 makeCollection objs url = Collection
197 { _cTotalItems = Just (length objs)
198 , _cItems = objs
199 , _cURL = url
200 }
446 $ HM.insert "totalItems" (toJSON (length objs))
447 $ HM.insert "items" (toJSON objs)
448 $ HM.insert "url" (toJSON url)
449 $ HM.empty
1 {-# LANGUAGE Rank2Types #-}
2 {-# LANGUAGE OverloadedStrings #-}
13 {-# LANGUAGE TemplateHaskell #-}
24
3 module Codec.ActivityStream.Schema where
4
5 import Data.Aeson hiding (Object)
6 import Data.Aeson.TH
7 import Data.DateTime
8 import Data.Text (Text)
5 {-|
6 Module : Codec.ActivityStream.Schema
7 Description : An interface to the Activity Streams Base Schema
8 Copyright : (c) Getty Ritter, 2014
9 Maintainer : gdritter@galois.com
10
11 This is an interface to the extended ActivityStreams schema which defines
12 an extensive set of @verb@ values, additional @objectType@ values, and a
13 set of extended properties for 'Object's.
14
15 Most of the inline documentation is drawn directly from the
16 <https://github.com/activitystreams/activity-schema/blob/master/activity-schema.md Activity Base Schema draft>
17 specification, with minor modifications
18 to refer to the corresponding data types in this module and to clarify
19 certain aspects. This is not an approved draft, and as such may be
20 subject to changes which will be reflected in this module. In contrast to
21 "Codec.ActivityStream", the API in this module makes
22 __no guarantees about long-term stability__.
23 -}
24
25 module Codec.ActivityStream.Schema
26 ( module Codec.ActivityStream
27 -- * Verbs
28 , SchemaVerb(..)
29 -- * Object Types
30 , SchemaObjectType(..)
31 -- ** Audio/Video
32 , avEmbedCode
33 , avStream
34 -- ** Binary
35 , bnCompression
36 , bnData
37 , bnFileUrl
38 , bnLength
39 , bnMd5
40 , bnMimeType
41 -- ** Event
42 , evAttendedBy
43 , evAttending
44 , evEndTime
45 , evInvited
46 , evMaybeAttending
47 , evNotAttendedBy
48 , evNotAttending
49 , evStartTime
50 -- ** Issue
51 , isTypes
52 -- ** Permission
53 , pmScope
54 , pmActions
55 -- ** Place
56 , plPosition
57 , plAddress
58 -- *** PlacePosition
59 , PlacePosition
60 -- *** PlaceAddress
61 , PlaceAddress
62 -- ** Role/Group
63 , rlMembers
64 -- ** Task
65 , tsActor
66 , tsBy
67 , tsObject
68 , tsPrerequisites
69 , tsRequired
70 , tsSupersedes
71 , tsVerb
72 -- * Basic Extension Properties
73 , acContext
74 , getLocation
75 , oMood
76 , oRating
77 , acResult
78 , getSource
79 , getStartTime
80 , getEndTime
81 , oTags
82 -- * Mood
83 , Mood
84 , moodRest
85 , moodDisplayName
86 , moodImage
87 ) where
88
89 import qualified Data.Aeson as Aeson
90 import Data.Aeson.TH (deriveJSON)
91 import Data.DateTime (DateTime)
92 import Data.Aeson ( FromJSON(..), ToJSON(..) )
93 import qualified Data.HashMap.Strict as HM
94 import Data.Text (Text)
995
1096 import Codec.ActivityStream.Internal
11 import Codec.ActivityStream.Representation
97 import Codec.ActivityStream.LensInternal
98 import Codec.ActivityStream
1299
13100 -- | The ActivityStreams Base Schema specification defines the
14101 -- following core verbs in addition to the default post verb that is
547634
548635 deriveJSON (commonOptsCC "") ''SchemaObjectType
549636
550 type SchemaObject = Object SchemaObjectType
551 type SchemaCollection = Collection SchemaObjectType
552
553 data AVObj = AVObj
554 { avEmbedCode :: Maybe Text
555 , avStream :: Maybe MediaLink
556 , avRest :: SchemaObject
557 } deriving (Eq, Show)
558
559 data BinaryObj = BinaryObj
560 { bnCompression :: Maybe Text
561 , bnData :: Maybe Text
562 , bnFileUrl :: Maybe Text
563 , bnLength :: Maybe Int
564 , bnMd5 :: Maybe Text
565 , bnMimeType :: Maybe Text
566 , bnRest :: SchemaObject
567 } deriving (Eq, Show)
568
569 data EventObj = EventObj
570 { evAttendedBy :: Maybe SchemaCollection
571 , evAttending :: Maybe SchemaCollection
572 , evEndTime :: Maybe DateTime
573 , evInvited :: Maybe SchemaCollection
574 , evMaybeAttending :: Maybe SchemaCollection
575 , evNotAttendedBy :: Maybe SchemaCollection
576 , evNotAttending :: Maybe SchemaCollection
577 , evStartTime :: Maybe DateTime
578 , evRest :: SchemaObject
579 } deriving (Eq, Show)
580
581 data IssueObj = IssueObj
582 { isTypes :: Maybe [Text]
583 , isRest :: SchemaObject
584 } deriving (Eq, Show)
585
586 data PlaceObj = PlaceObj
587 { plPosition :: Maybe PlacePositionObj
588 , plAddress :: Maybe PlaceAddressObj
589 , plRest :: SchemaObject
590 } deriving (Eq, Show)
591
592 data PlacePositionObj = PlacePositionObj
593 { ppAltitude :: Integer
594 , ppLatitude :: Integer
595 , ppLongitude :: Integer
596 } deriving (Eq, Show)
597
598 data PlaceAddressObj = PlaceAddressObj
599 { paFormatted :: Text
600 , paStreetAddress :: Text
601 , paLocality :: Text
602 , paRegion :: Text
603 , paPostalCode :: Text
604 , paCountry :: Text
605 } deriving (Eq, Show)
606
607 data TaskObj = TaskObj
608 { tsActor :: Maybe SchemaObject
609 , tsBy :: Maybe DateTime
610 , tsObject :: Maybe SchemaObject
611 , tsPrerequisites :: Maybe [TaskObj]
612 , tsRequired :: Maybe Bool
613 , tsSupersedes :: Maybe [TaskObj]
614 , tsVerb :: Maybe SchemaVerb
615 , tsRest :: SchemaObject
616 } deriving (Eq, Show)
637
638 -- audio/video
639
640 -- | A fragment of HTML markup that, when embedded within another HTML
641 -- page, provides an interactive user-interface for viewing or listening
642 -- to the video or audio stream.
643 avEmbedCode :: Lens' Object (Maybe Text)
644 avEmbedCode = makeAesonLensMb "embedCode" oRest
645
646 -- | An Activity Streams Media Link to the video or audio content itself.
647 avStream :: Lens' Object (Maybe MediaLink)
648 avStream = makeAesonLensMb "stream" oRest
649
650 -- binary
651
652 -- | An optional token identifying a compression algorithm applied to
653 -- the binary data prior to Base64-encoding. Possible algorithms
654 -- are "deflate" and "gzip", respectively indicating the use of
655 -- the compression mechanisms defined by RFC 1951 and RFC 1952.
656 -- Additional compression algorithms MAY be used but are not defined
657 -- by this specification. Note that previous versions of this
658 -- specification allowed for multiple compression algorithms to be
659 -- applied and listed using a comma-separated format. The use of
660 -- multiple compressions is no longer permitted.
661 bnCompression :: Lens' Object (Maybe Text)
662 bnCompression = makeAesonLensMb "compression" oRest
663
664 -- | The URL-Safe Base64-encoded representation of the binary data
665 bnData :: Lens' Object (Maybe Text)
666 bnData = makeAesonLensMb "data" oRest
667 -- | An optional IRI for the binary data described by this object.
668 bnFileUrl :: Lens' Object (Maybe Text)
669 bnFileUrl = makeAesonLensMb "fileUrl" oRest
670
671 -- | The total number of unencoded, uncompressed octets contained
672 -- within the "data" field.
673 bnLength :: Lens' Object (Maybe Text)
674 bnLength = makeAesonLensMb "length" oRest
675
676 -- | An optional MD5 checksum calculated over the unencoded,
677 -- uncompressed octets contained within the "data" field
678 bnMd5 :: Lens' Object (Maybe Text)
679 bnMd5 = makeAesonLensMb "md5" oRest
680
681 -- | The MIME Media Type of the binary data contained within the object.
682 bnMimeType :: Lens' Object (Maybe Text)
683 bnMimeType = makeAesonLensMb "mimeType" oRest
684
685 -- event
686
687 -- | A collection object as defined in Section 3.5 of the JSON
688 -- Activity Streams specification that provides information about
689 -- entities that attended the event.
690 evAttendedBy :: Lens' Object (Maybe Collection)
691 evAttendedBy = makeAesonLensMb "attendedBy" oRest
692
693 -- | A collection object as defined in Section 3.5 of the JSON
694 -- Activity Streams specification that provides information about
695 -- entities that intend to attend the event.
696 evAttending :: Lens' Object (Maybe Collection)
697 evAttending = makeAesonLensMb "attending" oRest
698
699 -- | The date and time that the event ends represented as a String
700 -- conforming to the "date-time" production in [RFC3339].
701 evEndTime :: Lens' Object (Maybe DateTime)
702 evEndTime = makeAesonLensMb "endTime" oRest
703
704 -- | A collection object as defined in Section 3.5 of the JSON
705 -- Activity Streams specification that provides information about
706 -- entities that have been invited to the event.
707 evInvited :: Lens' Object (Maybe Collection)
708 evInvited = makeAesonLensMb "invited" oRest
709
710 -- | A collection object as defined in Section 3.5 of the JSON
711 -- Activity Streams specification that provides information about
712 -- entities that possibly may attend the event.
713 evMaybeAttending :: Lens' Object (Maybe Collection)
714 evMaybeAttending = makeAesonLensMb "maybeAttending" oRest
715
716 -- | A collection object as defined in Section 3.5 of the JSON
717 -- Activity Streams specification that provides information about
718 -- entities that did not attend the event.
719 evNotAttendedBy :: Lens' Object (Maybe Collection)
720 evNotAttendedBy = makeAesonLensMb "notAttendedBy" oRest
721
722 -- | A collection object as defined in Section 3.5 of the JSON
723 -- Activity Streams specification that provides information about
724 -- entities that do not intend to attend the event.
725 evNotAttending :: Lens' Object (Maybe Collection)
726 evNotAttending = makeAesonLensMb "notAttending" oRest
727
728 -- | The date and time that the event begins represented as a String
729 -- confirming to the "date-time" production in RFC 3339.
730 evStartTime :: Lens' Object (Maybe DateTime)
731 evStartTime = makeAesonLensMb "startTime" oRest
732
733 -- issue
734
735 -- | An array of one or more absolute IRI's that describe the type of
736 -- issue represented by the object. Note that the IRI's are intended
737 -- for use as identifiers and MAY or MAY NOT be dereferenceable.
738 isTypes :: Lens' Object (Maybe [Text])
739 isTypes = makeAesonLensMb "types" oRest
740
741 -- permission
742
743 -- | A single Activity Streams Object, of any objectType, that
744 -- identifies the scope of the permission. For example, if the
745 -- permission objects describes write permissions for a given file,
746 -- the scope property would be a file object describing that file.
747 pmScope :: Lens' Object (Maybe Object)
748 pmScope = makeAesonLensMb "scope" oRest
749
750 -- | An array of Strings that identify the specific actions associated
751 -- with the permission. The actions are application and scope
752 -- specific. No common, core set of actions is defined by this
753 -- specification.
754 pmActions :: Lens' Object (Maybe [Text])
755 pmActions = makeAesonLensMb "actions" oRest
756
757 -- place
758
759 -- | The latitude, longitude and altitude of the place as a point on
760 -- Earth. Represented as a JSON Object as described below.
761 plPosition :: Lens' Object (Maybe PlacePosition)
762 plPosition = makeAesonLensMb "position" oRest
763
764 -- | A physical address represented as a JSON object as described below.
765 plAddress :: Lens' Object (Maybe PlaceAddress)
766 plAddress = makeAesonLensMb "address" oRest
767
768 newtype PlacePosition = PPO { fromPPO :: Aeson.Object } deriving (Eq, Show)
769
770 instance FromJSON PlacePosition where
771 parseJSON (Aeson.Object o) = do
772 ensure "Position" o
773 ["altitude", "latitude", "longitude"]
774 return (PPO o)
775 parseJSON _ = fail "\"Position\" not an object"
776
777 instance ToJSON PlacePosition where
778 toJSON = Aeson.Object . fromPPO
779
780 newtype PlaceAddress = PAO { fromPAO :: Aeson.Object } deriving (Eq, Show)
781
782 instance FromJSON PlaceAddress where
783 parseJSON (Aeson.Object o) = do
784 ensure "Address" o
785 [ "formatted"
786 , "streetAddress"
787 , "locality"
788 , "postalCode"
789 , "country"
790 ]
791 return (PAO o)
792 parseJSON _ = fail "Address not an object"
793
794 instance ToJSON PlaceAddress where
795 toJSON = Aeson.Object . fromPAO
796
797 -- role/group
798
799 -- | An optional Activity Streams Collection object listing the
800 -- members of a group, or listing the entities assigned to a
801 -- particular role.
802 rlMembers :: Lens' Object (Maybe [Object])
803 rlMembers = makeAesonLensMb "members" oRest
804
805 -- Task
806
807 -- | An Activity Streams Object that provides information about the
808 -- actor that is expected to complete the task.
809 tsActor :: Lens' Object (Maybe Object)
810 tsActor = makeAesonLensMb "actor" oRest
811
812 -- | A RFC 3339 date-time specifying the date and time by which the
813 -- task is to be completed.
814 tsBy :: Lens' Object (Maybe DateTime)
815 tsBy = makeAesonLensMb "by" oRest
816
817 -- | An Activity Streams object describing the object of the task.
818 tsObject :: Lens' Object (Maybe Object)
819 tsObject = makeAesonLensMb "object" oRest
820
821 -- | An Array of other Task objects that are to be completed before
822 -- this task can be completed.
823 tsPrerequisites :: Lens' Object (Maybe [Object])
824 tsPrerequisites = makeAesonLensMb "prerequisites" oRest
825
826 -- | A boolean value indicating whether completion of this task is
827 -- considered to be mandatory.
828 tsRequired :: Lens' Object (Maybe Bool)
829 tsRequired = makeAesonLensMb "required" oRest
830
831 -- | An Array of other Task objects that are superseded by this task object.
832 tsSupersedes :: Lens' Object (Maybe [Object])
833 tsSupersedes = makeAesonLensMb "supersedes" oRest
834
835 -- | A string indicating the verb for this task as defined in Section
836 -- 3.2 of [activitystreams].
837 tsVerb :: Lens' Object (Maybe SchemaVerb)
838 tsVerb = makeAesonLensMb "verb" oRest
839
840 -- extra properties
841
842 -- | The additional @context@ property allows an 'Activity' to further
843 -- include information about why a particular action occurred by
844 -- providing details about the context within which a particular
845 -- Activity was performed. The value of the @context@ property is an
846 -- 'Object' of any @objectType@. The meaning of the @context@ property is
847 -- only defined when used within an 'Activity' object.
848 acContext :: Lens' Activity (Maybe Object)
849 acContext = makeAesonLensMb "context" acRest
850
851 -- | When appearing within an activity, the location data indicates
852 -- the location where the activity occurred. When appearing within an
853 -- object, the location data indicates the location of that object at
854 -- the time the activity occurred.
855 getLocation :: Lens' a Aeson.Object -> Lens' a (Maybe Object)
856 getLocation = makeAesonLensMb "location"
857
858 -- | Mood describes the mood of the user when the activity was
859 -- performed. This is usually collected via an extra field in the user
860 -- interface used to perform the activity. For the purpose of the
861 -- schema, a mood is a freeform, short mood keyword or phrase along
862 -- with an optional mood icon image.
863 oMood :: Lens' Object (Maybe Mood)
864 oMood = makeAesonLensMb "mood" oRest
865
866 -- | A rating given as a number between 1.0 and 5.0 inclusive with one
867 -- decimal place of precision. Represented in JSON as a property
868 -- called @rating@ whose value is a JSON number giving the rating.
869 oRating :: Lens' Object (Maybe Double)
870 oRating = makeAesonLensMb "rating" oRest
871
872 -- | The @result@ provides a description of the result of any particular
873 -- activity. The value of the @result@ property is an Object of any
874 -- objectType. The meaning of the @result@ property is only defined when
875 -- used within an 'Activity' object.
876 acResult :: Lens' Activity (Maybe Object)
877 acResult = makeAesonLensMb "result" acRest
878
879 -- | The @source@ property provides a reference to the original source of
880 -- an object or activity. The value of the @source@ property is an
881 -- Object of any objectType.
882 --
883 -- The @source@ property is closely related to
884 -- the @generator@ and @provider@ properties but serves the distinct
885 -- purpose of identifying where the activity or object was originally
886 -- published as opposed to identifying the applications that generated
887 -- or published it.
888 getSource :: Lens' a Aeson.Object -> Lens' a (Maybe Object)
889 getSource = makeAesonLensMb "source"
890
891 -- | When an long running Activity occurs over a distinct period of
892 -- time, or when an Object represents a long-running process or event,
893 -- the @startTime@ propertiy can be used to specify the
894 -- date and time at which the activity or object begins.
895 -- The values for each are represented as JSON Strings
896 -- conforming to the "date-time" production in RFC3339.
897 getStartTime :: Lens' a Aeson.Object -> Lens' a (Maybe Text)
898 getStartTime = makeAesonLensMb "startTime"
899
900 -- | When an long running Activity occurs over a distinct period of
901 -- time, or when an Object represents a long-running process or event,
902 -- the @endTime@ propertiy can be used to specify the
903 -- date and time at which the activity or object concludes.
904 -- The values for each are represented as JSON Strings
905 -- conforming to the "date-time" production in RFC3339.
906 getEndTime :: Lens' a Aeson.Object -> Lens' a (Maybe Text)
907 getEndTime = makeAesonLensMb "endTime"
908
909 -- | A listing of the objects that have been associated with a
910 -- particular object. Represented in JSON using a property named @tags@
911 -- whose value is an Array of objects.
912 oTags :: Lens' Object (Maybe [Object])
913 oTags = makeAesonLensMb "tags" oRest
914
915 -- mood
916
917 -- | Mood describes the mood of the user when the activity was
918 -- performed. This is usually collected via an extra field in the user
919 -- interface used to perform the activity. For the purpose of this
920 -- schema, a mood is a freeform, short mood keyword or phrase along
921 -- with an optional mood icon image.
922 newtype Mood = Mood { fromMood :: Aeson.Object } deriving (Eq, Show)
923
924 instance FromJSON Mood where
925 parseJSON (Aeson.Object o) = do
926 ensure "Mood" o ["displayname", "image"]
927 return (Mood o)
928 parseJSON _ = fail "Mood not an object"
929
930 instance ToJSON Mood where
931 toJSON = Aeson.Object . fromMood
932
933 -- | Access to the underlying JSON object of a 'Mood'
934 moodRest :: Lens' Mood Aeson.Object
935 moodRest = makeLens fromMood (\ o' m -> m { fromMood = o' })
936
937 -- | The natural-language, human-readable and plain-text keyword or
938 -- phrase describing the mood. HTML markup MUST NOT be included.
939 moodDisplayName :: Lens' Mood Text
940 moodDisplayName = makeAesonLens "displayName" moodRest
941
942 -- | An optional image that provides a visual representation of the mood.
943 moodImage :: Lens' Mood MediaLink
944 moodImage = makeAesonLens "image" moodRest
11 {-# LANGUAGE TemplateHaskell #-}
2
3 {-|
4 Module : Codec.ActivityStream
5 Description : The basic Activity Streams structures
6 Copyright : (c) Getty Ritter, 2014
7 Maintainer : gdritter@galois.com
8
9 This is an interface to ActivityStreams that simply wraps an underlying
10 @aeson@ Object, and exposes a set of convenient lenses to access the
11 values inside. If an @aeson@ object appears wrapped in some respective wrapper,
12 it will necessarily contain the obligatory values for that type
13 (e.g. an 'Activity' is guaranteed to have a @published@ date.)
14
15 Most of the inline documentation is drawn directly from the
16 <http://activitystrea.ms/specs/json/1.0/ JSON Activity Streams 1.0>
17 specification, with minor modifications
18 to refer to the corresponding data types in this module and to clarify
19 certain aspects.
20 -}
221
322 module Codec.ActivityStream
423 ( module Codec.ActivityStream.Representation
1 -- Initial activitystreams-aeson.cabal generated by cabal init. For
2 -- further documentation, see http://haskell.org/cabal/users-guide/
1 name: activitystreams-aeson
2 version: 0.2.0.0
3 synopsis: An interface to the ActivityStreams specification
4 description: An interface to the
5 <http://activitystrea.ms/ Activity Streams>
6 specifications, using an @aeson@-based representation
7 of the underlying ActivityStream structures.
38
4 name: activitystreams-aeson
5 version: 0.1.0.0
6 -- synopsis:
7 -- description:
9 An ActivityStream is a representation of social
10 activities in JSON format, using a standard set of
11 structures. The specification is very flexible in
12 allowing most fields to be omitted, while also
13 allowing arbitrary new fields to be created when
14 necessary. This library attempts to maximize
15 type safety while retaining the flexibility present
16 in the specification.
817 license: BSD3
918 license-file: LICENSE
1019 author: Getty Ritter
1120 maintainer: gettylefou@gmail.com
12 -- copyright:
21 copyright: (c) 2014 Getty Ritter
1322 category: Codec
1423 build-type: Simple
15 -- extra-source-files:
1624 cabal-version: >=1.10
1725
1826 library
19 exposed-modules: Codec.ActivityStream.Dynamic,
20 Codec.ActivityStream.DynamicSchema,
27 exposed-modules: Codec.ActivityStream
28 Codec.ActivityStream.Schema
29 other-modules: Codec.ActivityStream.Internal,
2130 Codec.ActivityStream.Representation,
22 Codec.ActivityStream.Schema,
23 Codec.ActivityStream
24 other-modules: Codec.ActivityStream.Internal,
2531 Codec.ActivityStream.LensInternal
26 build-depends: base >=4.7 && <4.8,
27 aeson,
28 text,
29 url,
30 lens,
31 datetime,
32 unordered-containers,
33 network-uri
32 build-depends: base >=4.7 && <4.8,
33 aeson ==0.8.*,
34 text >=1.1,
35 datetime ==0.2.*,
36 unordered-containers >=0.2.5
3437 default-language: Haskell2010