packages feed

eros-client (empty) → 0.4.0.0

raw patch · 9 files changed

+424/−0 lines, 9 filesdep +aesondep +aeson-prettydep +basesetup-changed

Dependencies added: aeson, aeson-pretty, base, bytestring, containers, eros, text

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Peter Harpending++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 Peter Harpending 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.
+ README.md view
@@ -0,0 +1,130 @@+# eros-client++This is a command line interface to the+[eros library](https://github.com/pharpend/eros).++# Usage - v.0.4.0.0++This is a usage guide for version 0.4.0.0. There will be more up-to-date usage+guides as more versions come, hopefully.++To install, run `cabal install eros-client-0.4.0.0`.++The only way to interact with the library, for the time being is through the+client I built, `erosc`. It accepts input in Javascript Object Notation (JSON)+through `stdin`.++Here is the schema for the input:++```json+{+  "name": "erosc-input",+  "type": "object",+  "description": "The schema for the input to erosc.",+  "properties": {+    "text": {+      "type": "string",+      "description": "The text you want to be checked against the phraselists.",+      "required": true+    },+    "eros-lists": {+      "type": "array",+      "description": "The phraselists provided by eros you want \"text\" to be checked against.",+      "required": true,+      "items": {+        "type": "string"+      }+    },+  }+}+```++That is the up-to-date schema, as of version 0.4.0.0 . It is liable to+change. If the version you downloaded is greater than 0.4.0.0, make sure to+check the schema (it is distributed with the package) to make sure it is up to+date. The schema is located in `res/schemata/erosc-input.json`.++`erosc` will take that input, and send back output in JSON, in accordance with+the schema found in `res/schemata/erosc-output.json`.++```json+{+  "name": "erosc-output",+  "type": "array",+  "description": "The output of erosc.",+  "items": {+    "type": "object",+    "description": "The phraselist name, along with the score for that phraselist.",+    "properties": {+      "eros-list": {+        "type": "string",+        "description": "The name of the phraselist corresponding to this object."+      },+      "score": {+        "type": "number",+        "description": "The score corresponding to this phraselist."+      }+    }+  }+}+```++## Example++This is the example input from `res/erosc-dummy-inputs/input0.json`.++```json+{+  "text": "Fuck you, you fucking fuck! Fucking bitch tits milf sex sluts!",+  "eros-lists": [+    "gambling",+    "pornography"+  ]+}+```++Running `erosc < res/erosc-dummy-inputs/input0.json` yields++```json+[+  {+    "score": 0,+    "eros-list": "gambling"+  },+  {+    "score": 11394,+    "eros-list": "pornography"+  }+]+```++# Contributing++I would love if people would contribute. This client is BSD-licensed, so you can+pretty much do whatever you want with it.++If you have any ideas, don't hesitate to contact me.++## Planned features++### `erosc` ⟶ `eros-server`++As it stands, `erosc` is tedious and a bit difficult to use. I plan on rewriting+`erosc` to act as an HTTP[s] server, using Happstack, using acid-state as a RAM+cloud. This will be the fastest and easiest to maintain solution.++I will still include an offline client, but it won't be the focus of+development.++### More options++I need to add more filtering options, such as phraselist-specific thresholds,+custom phraselists, and, well, just more stuff.++# Contact++The best way to contact me is via IRC. I hang out a lot on `#archlinux` and+`#haskell` on the FreeNode network. My nicks are `l0cust` and `isomorpheous`.++You can also email me at <pharpend2@gmail.com>, although I'm not great at+checking that email address.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ eros-client.cabal view
@@ -0,0 +1,44 @@+name:                eros-client+version:             0.4.0.0+synopsis:            A command-line interface to the eros library.+description:+  This is a command-line interface to the+  <https://github.com/pharpend/eros eros library>.++  It is terrible at the moment, and will be deprecated before version 0.5.0.0,+  so it isn't a huge priority.++license:             BSD3+license-file:        LICENSE+author:              Peter Harpending+maintainer:          Peter Harpending <pharpend2@gmail.com>+copyright:           2014, Peter Harpending.+category:            Text+build-type:          Simple+data-files:+  res/schemata/*.json+cabal-version:       >=1.10+extra-source-files:+  README.md+  res/erosc-dummy-inputs/*.json+  res/schemata/*.json++executable erosc+  build-depends:+      aeson+    , aeson-pretty+    , base          >=4.7 && <4.8+    , bytestring+    , containers+    , eros          ==0.4.0.0+    , text+  hs-source-dirs:   src/+  main-is:          Main.lhs+  other-modules:    Erosc.Processor+  default-language: Haskell2010+  ghc-options:      -Wall++source-repository head+  type:     git+  location: https://github.com/pharpend/eros-client.git+  branch:   master
+ res/erosc-dummy-inputs/input0.json view
@@ -0,0 +1,7 @@+{+  "text": "Fuck you, you fucking fuck! Fucking bitch tits milf sex sluts!",+  "eros-lists": [+    "gambling",+    "pornography"+  ]+}
+ res/schemata/erosc-input.json view
@@ -0,0 +1,20 @@+{+  "name": "erosc-input",+  "type": "object",+  "description": "The schema for the input to erosc.",+  "properties": {+    "text": {+      "type": "string",+      "description": "The text you want to be checked against the phraselists.",+      "required": true+    },+    "eros-lists": {+      "type": "array",+      "description": "The phraselists provided by eros you want \"text\" to be checked against.",+      "required": true,+      "items": {+        "type": "string"+      }+    },+  }+}
+ res/schemata/erosc-output.json view
@@ -0,0 +1,19 @@+{+  "name": "erosc-output",+  "type": "array",+  "description": "The output of erosc.",+  "items": {+    "type": "object",+    "description": "The phraselist name, along with the score for that phraselist.",+    "properties": {+      "eros-list": {+        "type": "string",+        "description": "The name of the phraselist corresponding to this object."+      },+      "score": {+        "type": "number",+        "description": "The score corresponding to this phraselist."+      }+    }+  }+}
+ src/Erosc/Processor.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}++-- |This is the module which actually processes the marshals the+-- data. As far as erosc goes, this is the meat & potatoes.+-- +-- Basically, Main.hs was getting to be too long, so I created this+-- file.+-- +-- Copyright (c) 2014, Peter Harpending <pharpend2@gmail.com>. All+-- Rights Reserved.+-- +-- I'm supposed to say "All Rights Reserved," but this is actuallly+-- BSD-licensed. So, really you can do whatever you want with+-- this. Have fun!++module Erosc.Processor where++-- One of these days, I'm going to figure out how to cut down on these+-- imports. +import           Control.Applicative+import           Control.Monad                         (mzero)+import           Data.Aeson                     hiding (encode)+import           Data.Aeson.Encode.Pretty+import qualified Data.ByteString.Lazy as LzByte+import qualified Data.Text.Lazy       as LzText+import           Text.Eros++-- |Okay, here's a function that actually does something. It takes an+-- 'Input' type, and process it.+processInput :: Input -> IO Output+processInput (Input txt lists) = do+    outLists <- mapM listPair lists+    return $ Output outLists+  where+    listPair :: ErosList -> IO (ErosList, Score)+    listPair ls = do+      pmap <- loadPhraseMap ls+      let scr = messageScore txt pmap+      return (ls, scr)++-- |This will print JSON in a pretty matter, using 2-space indents. I+-- have no idea why 4-space indents are the default.+encode :: ToJSON a => a -> LzByte.ByteString+encode = encodePretty' defConfig { confIndent = 2+                                 }++-- |We represent the input data in its own data type. This is needed+-- for JSON parsing, but it will also be useful down the road, when I+-- allow input that isn't JSON.+data Input = Input { text      :: LzText.Text+                   , erosLists :: [ErosList]+                   }++-- |This is pretty self-explanatory+instance FromJSON ErosList where+  parseJSON (String s) = case erosListByName (LzText.fromStrict s) of+                           Just list -> return list+                           Nothing   -> mzero+  parseJSON _          = mzero++-- |This is pretty self-explanatory+instance FromJSON Input where+  parseJSON (Object v) = Input+    <$> v .: "text"+    <*> v .: "eros-lists"+  parseJSON _          = mzero++-- |This is the output data type. I will make an instance of ToJSON+-- for this data type. Again, at the start, only JSON input and output+-- is existent.+data Output = Output { elScore :: [(ErosList, Score)] }++-- |Pretty self-explanatory+instance ToJSON ErosList where+  toJSON el = case erosNameByList el of+                Just nom -> toJSON nom+                Nothing  -> "There's probably a bug in the JSON parsing \+                            \library Eros uses. You should file a bug \+                            \report at https://github.com/pharpend/eros/issues."++-- |Pretty self-explanatory+instance ToJSON (ErosList, Score) where+  toJSON (el, sc) = object [ "eros-list" .= el+                           , "score"     .= sc+                           ]++-- |Pretty self-explanatory+instance ToJSON Output where+  toJSON (Output elm) = toJSON elm++-- |It's convenient to think of Scores as Scores, although, they are+-- truly ints.+type Score = Int
+ src/Main.lhs view
@@ -0,0 +1,78 @@+|This is the main module for the eros client. This is not the meat &+potatoes of the program, but this is the bread & butter.++> module Main where+++So, here are our imports. I would like to only have IO inputs, however+the import of 'Data.Aeson' is needed in order to keep the+'Erosc.Processor' module pure.++Essentially, I was faced with either making this module be tainted by+purity, or have the other module be pure.++My qualified imports are a bit obnoxious. Even though they aren't+needed, I find that using qualified names makes the code a bit less+confusing. That is, @LzByte.hGetContents@ is a lot more informative+than just @hGetContents@.++> import           Data.Aeson             as Aeson+> import qualified Data.ByteString.Lazy   as LzByte+> import           Erosc.Processor        as Erosc+> import qualified System.IO              as StdIO+++|Eventually, I'll need this data type when I use command line+arguments. For the moment, it's just a dummy type. So, enjoy it.++> data EroscOpts = EroscOpts++|So, this is the main function. Whoop de doo.  It sends the contents+of 'StdIO.stdin' to runBtStr.++Eventually, I'll add in command line argument parsing, and then we'll+have a use for the 'EroscOptions' type.++> main :: IO ()+> main = runBtStr =<< LzByte.hGetContents StdIO.stdin++|This function takes the input (presumably 'StdIO.stdin'), and tries+to decode it.++If it successfully decodes the input into the 'Erosc.Input' type,+it sends the newfound decoded input to 'runInput', which sends it to+the processor.++If it can't, the program will throw a tantrum and shit itself.++> runBtStr :: LzByte.ByteString -> IO ()+> runBtStr inputBt = do+>   let eitherJson = (Aeson.eitherDecode inputBt) :: Either String Erosc.Input+>   case eitherJson of+>     Left msg      -> fail msg+>     Right ecInput -> runInput ecInput+++There is an astonishing quantity of bureaucracy in this program. You+have to go through like 5 functions before you get to a function that+actually does something useful.++|Okay, so, we're getting closer to the part of the program that+actually does stuff (or further away, depending on the location from+whence you come).++'runInput' takes the 'Erosc.Input' object (I do hate that word), and+sends it to some function in 'Erosc' that actually mutates the+data. Well, it doesn't mutate it, obviously, because this is Haskell,+but you get the idea.++@result@ needs to be '(<-)'d because 'Erosc.processInput' needs to+read the phraselist JSON file. This is a result of poor library design+on my part. I will fix this in a future release.++> runInput :: Erosc.Input -> IO ()+> runInput ipt = do+>   result <- Erosc.processInput ipt+>   let jsonText = Erosc.encode result+>   LzByte.hPutStr StdIO.stdout jsonText+