2012-06-13 17 views
5

Mam istniejący program, który przyjmuje argumenty wiersza poleceń (nazwa użytkownika, hasło, data), a następnie korzysta z biblioteki Network.HTTP.Conduit, aby opublikować wiadomość XML na serwerze. Następnie analizuję wyniki, wykonuję trochę pracy i używam blaze-html do zapisania w pliku.Wywołanie sieci IO z poziomu haskeline

Wszystko działa jak urok; jednak myślałem, że będę używał haskeline, aby hasło nie było widoczne. Jestem w stanie stworzyć program wiersza poleceń, który pobiera wartości dostarczone przez użytkownika i wypisuje je, ale jeśli zadzwonię do funkcji wykorzystującej kanał, to nigdy nie wróci.

Oto kod naruszającym przepisy:

main = runInputT defaultSettings loop 
where 
    loop :: InputT IO() 
    loop = do 
     Just username <- getInputLine "WM username: " 
     Just password <- getPassword (Just '*') "WM password: " 
     Just date  <- getInputLine "Date (YYYYMMDD): " 

     outputStrLn "querying WM..." 
     clients <- lift $ getWMClients username password 
     outputStrLn "successfully retrieved client list from WM..." 

     let outHeader = renderHeader date username 

     reportString <- mapM (\x -> createString x clients) cList 

     lift $ writeFile (date ++ "_report.html") (outHeader ++ concat reportString) 
     outputStrLn "Done" 

Funkcja getWMClients funkcji jest następująca:

getWMClients :: Username -> String -> IO [Client] 
getWMClients username password = do 
    let f = [Size "-1", Skip "0"] 
    let fs = [Select "id", 
       Select "status", 
       Select "last-name", 
       Select "first-name", 
      ] 
    let query = WMQuery {transaction=SHARE,service=Query,businessObject=CONT,field=f,fields=fs} 

    results <- doQuery username (Just password) Nothing (Just query) 
    rows <- xmlResultsToMaps results 

    let clients = map makeClient rows 
    return clients 

Kiedy uruchamiam program zawiesza się "odpytywanie WM ..." Nie sądzę Kanał http faktycznie działa. Jakieś wskazówki, jak to zrobić?

Dzięki z góry, Neil

Odpowiedz

1

Twierdzisz, że pracował z zakodowanej nazwę użytkownika, hasło, datę przed haskeline. Aby pomóc w debugowaniu, być może nie można podnieść przewodu do InputT. Czy poniższe nadal się nie udają? (Nie skompilowałem tego, więc możesz naprawić błędy składni ...)

-- Isolate the haskeline monad to just the input part: 
main = loop 
where 
    loop :: IO() 
    loop = do 
     (username,password,date) <- runInputT defaultSettings $ do 
     Just username <- getInputLine "WM username: " 
     Just password <- getPassword (Just '*') "WM password: " 
     Just date  <- getInputLine "Date (YYYYMMDD): " 
     return (username,password,date) 

     putStrLn "querying WM..." 
     clients <- getWMClients username password 
     putStrLn "successfully retrieved client list from WM..." 

     let outHeader = renderHeader date username 

     putString <- mapM (\x -> createString x clients) cList 

     writeFile (date ++ "_report.html") (outHeader ++ concat reportString) 
     putStrLn "Done" 
+0

Dzięki Chris, myślę, że problem polega na tym, że 'runInpuT' jest typu(). Kiedy próbuję tego, otrzymuję komunikat o błędzie: 'Nie można dopasować oczekiwanego typu'() 'z faktycznym typem '(t0, t1, t2)' W pierwszym argumencie' return ', a mianowicie '(nazwa użytkownika, hasło, data) " W wyrażeniu: return (nazwa użytkownika, hasło, data) W zgłoszeniu wyrażenia" do ": Tylko data <- getInputLine" Data (RRRRMMDD): "' – Neil

+0

Skończyło się na wyłudzaniu funkcja pętli osobno i zwracanie IO (String, String, String) i zadziałało. Dzięki za pomoc Chris. – Neil

Powiązane problemy