network-manager-tui (empty) → 0.1.0.0
raw patch · 8 files changed
+337/−0 lines, 8 filesdep +basedep +brickdep +hspecsetup-changed
Dependencies added: base, brick, hspec, microlens, network-manager-tui, process, split, vector, vty
Files
- LICENSE +30/−0
- README.md +25/−0
- Setup.hs +2/−0
- app/Main.hs +111/−0
- network-manager-tui.cabal +95/−0
- src/Lib.hs +47/−0
- src/Theme.hs +25/−0
- test/Spec.hs +2/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright andys8 (c) 2019++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 andys8 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,25 @@+# network-manager-tui++A simple network manager command-line tool++++## Dependencies++`nmcli` has to be installed++## Installation++### Clone repository++```sh+git clone https://github.com/andys8/network-manager-tui.git+cd network-manager-tui+stack install+```++## Usage++```sh+nmt+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,111 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}++module Main where+++import qualified Graphics.Vty as V+import qualified Brick.Main as M+import Brick.Types ( Widget )+import Brick.Themes ( themeToAttrMap )+import qualified Brick.Types as T+import qualified Brick.Widgets.Border as B+import qualified Brick.Widgets.Border.Style as BS+import qualified Brick.Widgets.Center as C+import Brick.Widgets.Core ( hLimit+ , str+ , vBox+ , hBox+ , padAll+ , padLeft+ , padRight+ , withAttr+ , withBorderStyle+ , (<+>)+ )+import qualified Brick.Widgets.List as L+import qualified Data.Vector as Vec+import Data.Maybe++import Lib+import Theme ( theme )+++type State = L.List () Connection+++main :: IO ()+main = do+ connections <- listConnections+ finalState <- M.defaultMain app (initialState connections)+ putStrLn =<< toggle finalState+++toggle :: State -> IO String+toggle state =+ fromMaybe (pure "") (toggleConnection . snd <$> L.listSelectedElement state)+++app :: M.App State e ()+app = M.App { M.appDraw = appDraw+ , M.appChooseCursor = M.showFirstCursor+ , M.appHandleEvent = appHandleEvent+ , M.appStartEvent = return+ , M.appAttrMap = const $ themeToAttrMap theme+ }+++appDraw :: State -> [Widget ()]+appDraw state =+ [ C.vCenter $ padAll 1 $ vBox+ [hBox [C.hCenter $ drawConnectionList state], str " ", instructions]+ ]+ where+ instructions = C.hCenter $ hLimit 100 $ hBox+ [ drawInstruction "HJ/arrows" "navigate"+ , drawInstruction "Enter" "connect/disconnect"+ , drawInstruction "Esc/Q" "exit"+ ]+++drawConnectionList :: L.List () Connection -> Widget ()+drawConnectionList list =+ withBorderStyle BS.unicodeBold+ $ B.borderWithLabel title+ $ hLimit 80+ $ L.renderList drawListElement True list+ where title = withAttr "title" $ str "Connections"+++drawListElement :: Bool -> Connection -> Widget ()+drawListElement _ connection = padLeft (T.Pad 1) $ padRight T.Max $ attr $ str+ content+ where+ content = "[" ++ _cType connection ++ "] " ++ _name connection+ attr | _active connection = withAttr "current"+ | otherwise = id++drawInstruction :: String -> String -> Widget n+drawInstruction keys action =+ C.hCenter $ withAttr "key" (str keys) <+> str " to " <+> withAttr+ "bold"+ (str action)+++appHandleEvent :: State -> T.BrickEvent () e -> T.EventM () (T.Next State)+appHandleEvent state (T.VtyEvent e) =+ let selectConnection = M.halt state+ deleteSelection = L.listClear state+ quit = M.halt deleteSelection+ in case e of+ V.EvKey V.KEsc [] -> quit+ V.EvKey (V.KChar 'q') [] -> quit+ V.EvKey V.KEnter [] -> selectConnection+ ev -> M.continue =<< L.handleListEventVi L.handleListEvent ev state++appHandleEvent state _ = M.continue state+++initialState :: [Connection] -> State+initialState connections = L.list () (Vec.fromList connections) 1+
+ network-manager-tui.cabal view
@@ -0,0 +1,95 @@+cabal-version: 2.0++-- This file has been generated from package.yaml by hpack version 0.31.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: b89d315c3145148a5e2aa3e71deafb7c0a383e745ab324f4132ce97dedcdc262++name: network-manager-tui+version: 0.1.0.0+synopsis: network-manager tui+description: Please see the README on GitHub at <https://github.com/andys8/network-manager-tui#readme>+category: Tui+homepage: https://github.com/andys8/network-manager-tui#readme+bug-reports: https://github.com/andys8/network-manager-tui/issues+author: andys8+maintainer: andys8@users.noreply.github.com+copyright: andys8+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md++source-repository head+ type: git+ location: https://github.com/andys8/network-manager-tui++flag static+ manual: True+ default: False++library network-manager-tui-lib+ exposed-modules:+ Lib+ Theme+ other-modules:+ Paths_network_manager_tui+ hs-source-dirs:+ src+ ghc-options: -Wall+ build-depends:+ base >=4.7 && <5+ , brick+ , microlens+ , process+ , split+ , vector+ , vty+ default-language: Haskell2010++executable nmt+ main-is: Main.hs+ other-modules:+ Paths_network_manager_tui+ autogen-modules:+ Paths_network_manager_tui+ hs-source-dirs:+ app+ build-depends:+ base >=4.7 && <5+ , brick+ , microlens+ , network-manager-tui-lib+ , process+ , split+ , vector+ , vty+ if flag(static)+ ghc-options: -static -threaded -rtsopts -with-rtsopts=-N+ cc-options: -static+ ld-options: -static -pthread+ else+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ default-language: Haskell2010++test-suite nmt-test+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Paths_network_manager_tui+ hs-source-dirs:+ test+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.7 && <5+ , brick+ , hspec+ , microlens+ , network-manager-tui-lib+ , process+ , split+ , vector+ , vty+ default-language: Haskell2010
+ src/Lib.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE NamedFieldPuns #-}+module Lib+ ( Connection(..)+ , toggleConnection+ , listConnections+ )+where++import System.Process+import Data.List.Split+import Data.List+import Data.Ord++data Connection = Connection { _uuid :: String, _cType :: String, _name:: String, _timestamp:: Int, _active:: Bool } deriving (Show, Eq)+++listConnections :: IO [Connection]+listConnections = toConnections <$> execReadConnections+ where+ execReadConnections = readProcess+ "nmcli"+ [ "--terse"+ , "--colors=no"+ , "--escape=yes"+ , "--fields=uuid,type,name,timestamp,active"+ , "connection"+ , "show"+ ]+ []+++toConnections :: String -> [Connection]+toConnections xs = sortOn (Down . _timestamp) $ toConnection <$> lines xs+++toConnection :: String -> Connection+toConnection x = Connection uuid cType name (read ts) (isActive active)+ where+ [uuid, cType, name, ts, active] = splitOn ":" x+ isActive "yes" = True+ isActive _ = False+++toggleConnection :: Connection -> IO String+toggleConnection Connection { _uuid, _active } =+ readProcess "nmcli" ["connection", if _active then "down" else "up", _uuid] []+
+ src/Theme.hs view
@@ -0,0 +1,25 @@+module Theme+ ( theme+ )+where++import Graphics.Vty+import qualified Brick.Widgets.List as List+import Brick.AttrMap ( attrName )+import Brick.Util+import Brick.Themes ( Theme+ , newTheme+ )++theme :: Theme+theme = newTheme+ (white `on` black)+ [ (List.listAttr , fg white)+ , (List.listSelectedAttr , fg brightWhite)+ , (List.listSelectedFocusedAttr, black `on` red)+ , (attrName "key" , withStyle (fg green) bold)+ , (attrName "bold" , withStyle (fg white) bold)+ , (attrName "current" , fg brightWhite)+ , (attrName "title" , withStyle (fg brightRed) bold)+ ]+
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"