diff options
Diffstat (limited to 'Presence/Stanza/Types.hs')
-rw-r--r-- | Presence/Stanza/Types.hs | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/Presence/Stanza/Types.hs b/Presence/Stanza/Types.hs new file mode 100644 index 00000000..6b402f4d --- /dev/null +++ b/Presence/Stanza/Types.hs | |||
@@ -0,0 +1,184 @@ | |||
1 | {-# LANGUAGE FlexibleInstances #-} | ||
2 | module Stanza.Types where | ||
3 | |||
4 | import Control.Concurrent.STM | ||
5 | import Data.Int | ||
6 | import Data.Text | ||
7 | import Data.XML.Types as XML | ||
8 | |||
9 | import Connection (PeerAddress(..)) | ||
10 | import ConnectionKey (ClientAddress(..)) | ||
11 | import LockedChan | ||
12 | import Nesting (Lang) | ||
13 | |||
14 | type Stanza = StanzaWrap (LockedChan XML.Event) | ||
15 | |||
16 | data StanzaWrap a = Stanza | ||
17 | { stanzaType :: StanzaType | ||
18 | , stanzaId :: Maybe Text | ||
19 | , stanzaTo :: Maybe Text | ||
20 | , stanzaFrom :: Maybe Text | ||
21 | , stanzaChan :: a | ||
22 | , stanzaClosers :: TVar (Maybe [XML.Event]) | ||
23 | , stanzaInterrupt :: TMVar () | ||
24 | , stanzaOrigin :: StanzaOrigin | ||
25 | } | ||
26 | |||
27 | data StanzaOrigin = LocalPeer | ||
28 | | PeerOrigin PeerAddress (TChan Stanza) | ||
29 | | ClientOrigin ClientAddress (TChan Stanza) | ||
30 | |||
31 | data StanzaType | ||
32 | = Unrecognized | ||
33 | | Ping | ||
34 | | Pong | ||
35 | | RequestResource (Maybe Text) (Maybe Text) -- ^ Client's name for this host followed by client's requested resource id. | ||
36 | | SetResource | ||
37 | | SessionRequest | ||
38 | | UnrecognizedQuery Name | ||
39 | | RequestRoster | ||
40 | | Roster | ||
41 | | RosterEvent { rosterEventType :: RosterEventType | ||
42 | , rosterUser :: Text | ||
43 | , rosterContact :: Text } | ||
44 | | Error StanzaError XML.Event | ||
45 | | PresenceStatus { presenceShow :: JabberShow | ||
46 | , presencePriority :: Maybe Int8 | ||
47 | , presenceStatus :: [(Lang,Text)] | ||
48 | , presenceWhiteList :: [Text] | ||
49 | } | ||
50 | | PresenceInformError | ||
51 | | PresenceInformSubscription Bool | ||
52 | | PresenceRequestStatus | ||
53 | | PresenceRequestSubscription Bool | ||
54 | | Message { msgThread :: Maybe MessageThread | ||
55 | , msgLangMap :: [(Lang,LangSpecificMessage)] | ||
56 | } | ||
57 | | NotifyClientVersion { versionName :: Text | ||
58 | , versionVersion :: Text } | ||
59 | | InternalEnableHack ClientHack | ||
60 | | InternalCacheId Text | ||
61 | deriving (Show,Eq) | ||
62 | |||
63 | data RosterEventType | ||
64 | = RequestedSubscription | ||
65 | | NewBuddy -- preceded by PresenceInformSubscription True | ||
66 | | RemovedBuddy -- preceded by PresenceInformSubscription False | ||
67 | | PendingSubscriber -- same as PresenceRequestSubscription | ||
68 | | NewSubscriber | ||
69 | | RejectSubscriber | ||
70 | deriving (Show,Read,Ord,Eq,Enum) | ||
71 | |||
72 | data ClientHack = SimulatedChatErrors | ||
73 | deriving (Show,Read,Ord,Eq,Enum) | ||
74 | |||
75 | |||
76 | data LangSpecificMessage = | ||
77 | LangSpecificMessage { msgBody :: Maybe Text | ||
78 | , msgSubject :: Maybe Text | ||
79 | } | ||
80 | deriving (Show,Eq) | ||
81 | |||
82 | data MessageThread = MessageThread { | ||
83 | msgThreadParent :: Maybe Text, | ||
84 | msgThreadContent :: Text | ||
85 | } | ||
86 | deriving (Show,Eq) | ||
87 | |||
88 | |||
89 | data JabberShow = Offline | ||
90 | | ExtendedAway | ||
91 | | Away | ||
92 | | DoNotDisturb | ||
93 | | Available | ||
94 | | Chatty | ||
95 | deriving (Show,Enum,Ord,Eq,Read) | ||
96 | |||
97 | class StanzaFirstTag a where | ||
98 | stanzaFirstTag :: StanzaWrap a -> IO XML.Event | ||
99 | instance StanzaFirstTag (TChan XML.Event) where | ||
100 | stanzaFirstTag stanza = do | ||
101 | e <-atomically $ peekTChan (stanzaChan stanza) | ||
102 | return e | ||
103 | instance StanzaFirstTag (LockedChan XML.Event) where | ||
104 | stanzaFirstTag stanza = do | ||
105 | e <-atomically $ peekLChan (stanzaChan stanza) | ||
106 | return e | ||
107 | instance StanzaFirstTag XML.Event where | ||
108 | stanzaFirstTag stanza = return (stanzaChan stanza) | ||
109 | |||
110 | data StanzaError | ||
111 | = BadRequest | ||
112 | | Conflict | ||
113 | | FeatureNotImplemented | ||
114 | | Forbidden | ||
115 | | Gone | ||
116 | | InternalServerError | ||
117 | | ItemNotFound | ||
118 | | JidMalformed | ||
119 | | NotAcceptable | ||
120 | | NotAllowed | ||
121 | | NotAuthorized | ||
122 | | PaymentRequired | ||
123 | | RecipientUnavailable | ||
124 | | Redirect | ||
125 | | RegistrationRequired | ||
126 | | RemoteServerNotFound | ||
127 | | RemoteServerTimeout | ||
128 | | ResourceConstraint | ||
129 | | ServiceUnavailable | ||
130 | | SubscriptionRequired | ||
131 | | UndefinedCondition | ||
132 | | UnexpectedRequest | ||
133 | deriving (Show,Enum,Ord,Eq) | ||
134 | |||
135 | xep0086 :: StanzaError -> (Text, Int) | ||
136 | xep0086 e = case e of | ||
137 | BadRequest -> ("modify", 400) | ||
138 | Conflict -> ("cancel", 409) | ||
139 | FeatureNotImplemented -> ("cancel", 501) | ||
140 | Forbidden -> ("auth", 403) | ||
141 | Gone -> ("modify", 302) | ||
142 | InternalServerError -> ("wait", 500) | ||
143 | ItemNotFound -> ("cancel", 404) | ||
144 | JidMalformed -> ("modify", 400) | ||
145 | NotAcceptable -> ("modify", 406) | ||
146 | NotAllowed -> ("cancel", 405) | ||
147 | NotAuthorized -> ("auth", 401) | ||
148 | PaymentRequired -> ("auth", 402) | ||
149 | RecipientUnavailable -> ("wait", 404) | ||
150 | Redirect -> ("modify", 302) | ||
151 | RegistrationRequired -> ("auth", 407) | ||
152 | RemoteServerNotFound -> ("cancel", 404) | ||
153 | RemoteServerTimeout -> ("wait", 504) | ||
154 | ResourceConstraint -> ("wait", 500) | ||
155 | ServiceUnavailable -> ("cancel", 503) | ||
156 | SubscriptionRequired -> ("auth", 407) | ||
157 | UndefinedCondition -> ("", 500) | ||
158 | UnexpectedRequest -> ("wait", 400) | ||
159 | |||
160 | errorText :: StanzaError -> Text | ||
161 | errorText e = case e of | ||
162 | BadRequest -> "Bad request" | ||
163 | Conflict -> "Conflict" | ||
164 | FeatureNotImplemented -> "This feature is not implemented" | ||
165 | Forbidden -> "Forbidden" | ||
166 | Gone -> "Recipient can no longer be contacted" | ||
167 | InternalServerError -> "Internal server error" | ||
168 | ItemNotFound -> "Item not found" | ||
169 | JidMalformed -> "JID Malformed" | ||
170 | NotAcceptable -> "Message was rejected" | ||
171 | NotAllowed -> "Not allowed" | ||
172 | NotAuthorized -> "Not authorized" | ||
173 | PaymentRequired -> "Payment is required" | ||
174 | RecipientUnavailable -> "Recipient is unavailable" | ||
175 | Redirect -> "Redirect" | ||
176 | RegistrationRequired -> "Registration required" | ||
177 | RemoteServerNotFound -> "Recipient's server not found" | ||
178 | RemoteServerTimeout -> "Remote server timeout" | ||
179 | ResourceConstraint -> "The server is low on resources" | ||
180 | ServiceUnavailable -> "The service is unavailable" | ||
181 | SubscriptionRequired -> "A subscription is required" | ||
182 | UndefinedCondition -> "Undefined condition" | ||
183 | UnexpectedRequest -> "Unexpected request" | ||
184 | |||