-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathDownload.hs
More file actions
105 lines (89 loc) · 4.46 KB
/
Download.hs
File metadata and controls
105 lines (89 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
module Download where
import Prelude hiding (error)
import Network.HTTP.Conduit
import Control.Exception as X
import qualified Data.ByteString.Lazy as BL hiding (pack, unpack)
import qualified Data.ByteString.Lazy.Char8 as BL
import Data.Monoid
import Data.Maybe
import System.Posix.Time
import GetHeaders
import BuildUrl
import Errors
import Types
import Utility
import Ops
import Auth
import DatTimer
import Mosaic
import Search
-- Download the dat file from the server.
getMsg :: Input -> IO (BL.ByteString, Int, String)
getMsg input = do
-- get the current time for authorization purposes
getCurrentTime <- epochTime
-- convert the current time to an integer
let currentTime = read . show $ getCurrentTime :: Integer
authenticationLogic currentTime
where
-- Make the url to download the dat file
makeUrl :: String -> Maybe String
makeUrl poolOrOyster = buildUrl poolOrOyster (server input) (board input) (post input)
-- Check for errors, if no error, then download and return dat file
authenticationLogic :: Integer -> IO (BL.ByteString, Int, String)
authenticationLogic currentTime
| anInputError = return inputError
| not . fst $ authenticate currentTime = return authenticationError
| isNothing (makeUrl "oyster") = return urlError
| isNothing (makeUrl "pool") = return urlError
| otherwise = do
limitBool <- isUserOverDatLimit userHash -- check if user is over speedlimit or not
if limitBool
then return timeLimitError -- if they are over the limit, return an error
else downloadAndReturnDatFile -- otherwise download and return dat file
where
-- Download the dat file and return it
-- It first checks oyster. If oyster returns 404 not found, then it will check pool. If pool also returns 404 not found,
-- then it prints "Error 13"
downloadAndReturnDatFile :: IO (BL.ByteString, Int, String)
downloadAndReturnDatFile = do
-- print $ userHash ++ " is authenticated"-- user is authenticated, continue and download the page -- Debugging
datFile <- getUrl oysterUrl
addUserToTimer userHash -- add the user's hash to the dat timer
if datFile == (fst' pageDoesNotExistError) || datFileExistence datFile
then do
datFilePool <- getUrl poolUrl -- check if pool exists or not
if datFilePool == (fst' pageDoesNotExistError) || datFileExistence datFilePool -- if pool doesnt exist, just return the error
then return pageDoesNotExistError -- this will return the error 13
else do
lModified <- lastModified poolUrl
return $ (mconcat [success, pool, n, processDatFile input datFilePool], 200, lModified) -- prepend success to pool
else do
lModified <- lastModified oysterUrl
return $ (mconcat [success, oyster, n, processDatFile input datFile], 200, lModified) -- prepend success to oyster
where
success = BL.pack "Success"
oyster = BL.pack " Archive"
n = BL.pack "\n"
pool = BL.pack " Pool"
live = BL.pack " Live"
statusExceptionHandler :: HttpException -> IO BL.ByteString
statusExceptionHandler e = (putStrLn "404 Not Found") >> {-- toLog "error" (show currentTime ++ " 404") >> --} (return $ fst' pageDoesNotExistError)
oysterUrl = fromMaybe "" $ makeUrl "oyster"
poolUrl = fromMaybe "" $ makeUrl "pool"
getUrl url' = simpleHttp url' `X.catch` statusExceptionHandler
lastModified url' = getLastModified url'
userHash = snd . authenticate $ currentTime
--processDatFile runs all the operations on the dat file for formatting
-- dont forget to run the mosaic! (replaceDates)
processDatFile input datFile = replaceDates ((startToEnd (start input) (end input) (keepFirst input) . lastN (Types.last input) (keepFirst input) $ datFile))
-- Shows whether the user is authenticated or not. If authenticated, then the Bool is true, and string contains their hashed name
-- if not authenticated then bool is false, and the string is just ""
-- The integer sent to authenticate is the currentTime
authenticate :: Integer -> (Bool, String)
authenticate = authenticateUser input -- Crypto related
-- Example:
-- sid = Just "sid=Monazilla/2.00:437576303V875807Q65482S5373415V0353657X819589B683935C83892l0684065u718984C13042Y073615439W33071V8555402N76303M0122748U5567915F128809I381065V6928103Q47334M0251341Y65808j5567915e7"
-- output an error if there is one
anInputError :: Bool
anInputError = fromMaybe False (error input)