postLabelsR :: Handler ()
postLabelsR = do
    text <- runInputPost $ ireq textField "tree"
    case maybeResult (parse json $ encodeUtf8 text) >>= go of
        Nothing -> invalidArgsI [MsgInvalidJsonInput text]
        Just x -> do
            runDB $ mapM_ (fix Nothing) x
            setMessageI MsgLabelsUpdated
            redirect RedirectTemporary LabelsR
  where
    fix parent lt = do
        update (lid lt) [LabelParent =. parent]
        mapM_ (fix $ Just $ lid lt) $ lchildren lt
    go (Array x) = mapM go' $ V.toList x
    go _ = Nothing
    go' (Object o) = do
        t <- Map.lookup "id" o
        t' <- go'' t
        c <- Map.lookup "children" o
        c' <- go c
        return $ LTree t' "ignored" c'
    go' _ = Nothing
    go'' (String t) = fromSinglePiece t
    go'' _ = Nothing
postLabelsR :: Handler ()
postLabelsR = do
    text <- runInputPost $ ireq textField "tree"
    case maybeResult (parse json $ encodeUtf8 text) >>= go of
        Nothing -> invalidArgsI [MsgInvalidJsonInput text]
        Just x -> do
            runDB $ mapM_ (fix Nothing) x
            setMessageI MsgLabelsUpdated
            redirect RedirectTemporary LabelsR
  where
    fix parent lt = do
        update (lid lt) [LabelParent =. parent]
        mapM_ (fix $ Just $ lid lt) $ lchildren lt
    go (Array x) = mapM go' $ V.toList x
    go _ = Nothing
    go' (Object o) = do
        t <- Map.lookup "id" o
        t' <- go'' t
        c <- Map.lookup "children" o
        c' <- go c
        return $ LTree t' "ignored" c'
    go' _ = Nothing
    go'' (String t) = fromSinglePiece t
    go'' _ = Nothing
postLabelsR = do
    text <- runInputPost $ ireq textField "tree"
    case maybeResult (parse json $ encodeUtf8 text) >>= go of
        Nothing -> invalidArgsI [MsgInvalidJsonInput text]
        Just x -> do
            runDB $ mapM_ (fix Nothing) x
            setMessageI MsgLabelsUpdated
            redirect RedirectTemporary LabelsR
  where
    fix parent lt = do
        update (lid lt) [LabelParent =. parent]
        mapM_ (fix $ Just $ lid lt) $ lchildren lt
    go (Array x) = mapM go' $ V.toList x
    go _ = Nothing
    go' (Object o) = do
        t <- Map.lookup "id" o
        t' <- go'' t
        c <- Map.lookup "children" o
        c' <- go c
        return $ LTree t' "ignored" c'
    go' _ = Nothing
    go'' (String t) = fromSinglePiece t
    go'' _ = Nothing