hellnet-0.1: Hellnet/URI.hs
module Hellnet.URI (parseHellnetURI, HellnetURI(..)) where
import Data.List
import Data.Maybe
import Hellnet
import Hellnet.Utils
import Safe
import Text.ParserCombinators.Parsec
import Text.Show
import Text.URI
data HellnetURI =
ChunkURI Hash -- ^ Chunk hash
(Maybe Key) -- ^ Encryption key
(Maybe String) -- ^ File name
| FileURI Hash -- ^ Filelink's start hash
(Maybe Key) -- ^ Encryption key
(Maybe String) -- ^ File name
| MetaURI KeyID -- ^ Meta public key ID
String -- ^ Meta name
String -- ^ Meta path
(Maybe Key) -- ^ Encryption key
(Maybe String) -- ^ File name
deriving (Eq)
instance Show HellnetURI where
show u = show uri where
uri = case u of
(ChunkURI hsh key fname) -> nullURI {
uriScheme = Just "hell"
, uriRegName = Just "chunk"
, uriPath = "/" ++ hashToHex hsh
, uriQuery = let ps = ([] ++ maybeToPairs key (hashToHex) "key" ++ maybeToPairs fname (id) "name") in if null ps then Nothing else Just (pairsToQuery ps)
}
(FileURI hsh key fname) -> nullURI {
uriScheme = Just "hell"
, uriRegName = Just "file"
, uriPath = "/" ++ hashToHex hsh
, uriQuery = let ps = ([] ++ maybeToPairs key (hashToHex) "key" ++ maybeToPairs fname (id) "name") in if null ps then Nothing else Just (pairsToQuery ps)
}
(MetaURI kid mname mpath key fname) -> nullURI {
uriScheme = Just "hell"
, uriRegName = Just "meta"
, uriPath = "/" ++ intercalate "/" [hashToHex kid, mname, mpath]
, uriQuery = let ps = ([] ++ maybeToPairs key (hashToHex) "key" ++ maybeToPairs fname (id) "name") in if null ps then Nothing else Just (pairsToQuery ps)
}
showList = showListWith (const show)
parseHellnetURI :: String -> Maybe HellnetURI
parseHellnetURI s = let
parsed = parseURI s in
maybe (Nothing) (parseHellnetURI') parsed
parseHellnetURI' :: URI -> Maybe HellnetURI
parseHellnetURI' u = let
params = uriQueryItems u in
if uriScheme u == Just "hell" then
let key = maybe (Nothing) (Just . hexToHash) $ lookup "key" params;
fname = lookup "name" params in
case fromMaybe "" (uriRegName u) of
"chunk" -> let hsh = hexToHash $ tailSafe $ uriPath u in
Just $ ChunkURI hsh key fname
"file" -> let hsh = hexToHash $ tailSafe $ uriPath u in
Just $ FileURI hsh key fname
"meta" -> let splitPath = explode '/' $ tailSafe $ uriPath u in
if length splitPath < 2 then Nothing
else
let keyId = hexToHash $ head splitPath;
metaName = splitPath !! 1;
metaPath = intercalate "/" $ drop 2 splitPath in
Just $ MetaURI keyId metaName metaPath key fname
otherwise -> Nothing
else Nothing
-- this is for constructing pairlists from maybes
maybeToPairs :: Maybe a -> (a -> String) -> String -> [(String, String)]
maybeToPairs a f name = maybe ([]) (\x -> [(uriescape name, uriescape (f x))]) a
uriescape = escapeString (okInQuery)