packages feed

hissmetrics (empty) → 0.1

raw patch · 4 files changed

+220/−0 lines, 4 filesdep +basedep +bytestringdep +conduitsetup-changed

Dependencies added: base, bytestring, conduit, http-conduit, http-types, text, time

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2012, Felipe Lessa <felipe.lessa@gmail.com>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Felipe Lessa <felipe.lessa@gmail.com> nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hissmetrics.cabal view
@@ -0,0 +1,36 @@+Name:                hissmetrics+Version:             0.1+Synopsis:            Unofficial API bindings to KISSmetrics.+Homepage:            https://github.com/meteficha/hissmetrics+License:             BSD3+License-file:        LICENSE+Author:              Felipe Lessa+Maintainer:          Felipe Lessa <felipe.lessa@gmail.com>+Category:            Web+Build-type:          Simple+Cabal-version:       >=1.6++Description:+  This package provides simple functions that allow you to access+  KISSmetrics using Haskell.+++Source-repository head+  type:     git+  location: git://github.com/meteficha/hissmetrics.git+++Library+  hs-source-dirs: src+  Exposed-modules:+    Web.KISSmetrics+  Build-depends:   base         >= 4.3     && < 5+                 , time         >= 1.1     && < 2+                 , bytestring+                 , text         >= 0.7     && < 0.12+                 , conduit      == 0.4.*+                 , http-types+                 , http-conduit == 1.4.*+  Extensions:+    RecordWildCards,+    OverloadedStrings
+ src/Web/KISSmetrics.hs view
@@ -0,0 +1,152 @@+-- | This module is meant to be imported qualified:+--+-- @+-- import qualified Web.KISSmetrics as KISSmetrics+-- @+module Web.KISSmetrics+    (+    ) where++import Control.Arrow (second)+import Data.Text (Text)+import Data.Time (UTCTime, formatTime)+import qualified Data.ByteString.Char8 as B8+import qualified Data.Conduit as C+import qualified Data.Conduit.List as CL+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE+import qualified Network.HTTP.Conduit as H+import qualified Network.HTTP.Types as H+++-- | Your KISSmetrics API key.+type APIKey = H.Ascii+++-- | KISSmetrics names and identities are limited to at most 255+-- characters and all commas (@,@) and colons (@:@) are changed+-- to spaces (@ @).  Nothing is checked by this Haskell library,+-- so be careful =).+type SimpleText = H.Ascii+++-- | A KISSmetrics property.  The property names needs to follow+-- the rules outlined on 'SimpleText'@'s@ documentation.  The+-- property value, on the other hand, are only limited to 8 KiB+-- and don't have any other restrictions.+type Property = (SimpleText, Text)+++-- | A timestamp used only to ignore duplicated events.+data Timestamp =+    Automatic+    -- ^ Use KISSmetrics' servers time as the timestamp.+  | Manual UTCTime+    -- ^ Use given time as the timestamp.+++data CallType =+    -- | Record an event.+    Record { eventName :: SimpleText+             -- ^ Name of the event being recorded.+           , identity :: SimpleText+             -- ^ Identity of the person doing the event.+           , timestamp :: Timestamp+             -- ^ See 'Timestamp'.+           , properties :: [Property]+             -- ^ Any additional properties you may want.+           }+    -- | Set user properties without recording an event.+  | SetProps { identity :: SimpleText+               -- ^ Identity of the person whose properties will+               -- to be changed.+             , timestamp :: Timestamp+               -- ^ See 'Timestamp'.+             , properties :: [Property]+               -- ^ Properties to be set.+             }+    -- | Alias two identities as the same one.+  | Alias { identity :: SimpleText+            -- ^ Identity of the person you're aliasing.+          , identity' :: SimpleText+            -- ^ Other identity you want to alias.+          }+++-- | Call KISSmetrics' API.  See 'CallType' for documentation+-- about which calls you may make.+--+-- Note that official KISSmetrics' APIs provide many functions+-- (usually four) while we provide just this one and a sum data+-- type.  This function alone does the work of @record@, @set@,+-- @identify@ and @alias@.+--+-- TODO: Currently there's no support for automatically retrying+-- failed request, you need to retry yourself.+call :: H.Manager  -- ^ HTTP connection manager (cf. 'H.newManager').+     -> APIKey     -- ^ Your KISSmetrics API key.+     -> CallType   -- ^ Which call you would like to make.+     -> IO ()+call manager apikey callType =+  C.runResourceT $ do+    -- Create the request+    let (path, args) = callInfo callType+        request =+          H.def { H.method = "GET"+                , H.secure = True+                , H.host   = "trk.kissmetrics.com"+                , H.path   = path+                , H.queryString =+                    H.renderSimpleQuery False $+                    ("_k", apikey) : args+                , H.redirectCount = 0+                }++    -- Make the call+    H.Response {..} <- H.http request manager++    -- By default http-conduit will already throw an exception on+    -- anything other than 200 Ok, so we don't need to check the+    -- response.  We consume it just to free the resources as early+    -- as possible.  (If we just closed and KISSmetrics decided to+    -- give an OK message in the body, the connection would not be+    -- keep-alived correctly.)+    responseBody C.$$ CL.sinkNull++++-- | Internal function.  Given a 'CallType', return the URL to be+-- used and generate a list of arguments.+callInfo :: CallType -> (H.Ascii, H.SimpleQuery)+callInfo Record {..} =+  ( "/e"+  , (:) ("_n", eventName) $+    (:) ("_p", identity) $+    timestampInfo timestamp $+    propsInfo properties+  )+callInfo SetProps {..} =+  ( "/s"+  , (:) ("_p", identity) $+    timestampInfo timestamp $+    propsInfo properties+  )+callInfo Alias {..} =+  ( "/a"+  , [("_p", identity), ("_n", identity')]+  )+++-- | Generate a difference list of arguments for a timestamp.+timestampInfo :: Timestamp+              -> (H.SimpleQuery -> H.SimpleQuery) -- ^ Difference list.+timestampInfo Automatic = id+timestampInfo (Manual t) =+  (:) ("_d", "1") .+  (:) ("_t", B8.pack $ formatTime locale "%s" t)+    where locale = error "Web.KISSmetrics.timestampInfo: locale shouldn't be needed."+++-- | Generate a list of arguments for a list of properties.+propsInfo :: [Property] -> H.SimpleQuery+propsInfo = map (second TE.encodeUtf8)