1 {-# LANGUAGE OverloadedStrings #-}
7 import System.Environment
9 import System.Directory
10 import Prelude hiding (init)
11 import Data.List (intercalate)
13 import Text.JSON.Generic
14 import Data.Text hiding (intercalate, unlines, init, length, splitAt)
15 import Data.Time.Clock.POSIX
16 import System.File.Tree hiding (mapM, mapM_)
17 import System.Directory (doesFileExist)
19 import Data.Text.Template
21 import Data.Text.Lazy (toStrict)
24 main = getArgs >>= parse
26 continueIfValidProject :: IO() -> IO ()
27 continueIfValidProject nextfn = do
28 jsonExists <- doesFileExist "xyz.json"
31 else putStrLn "This does not appear to be a valid project directory"
35 dirExists <- doesFileExist "xyz.json"
37 then putStrLn "Project already initialised"
38 else do createDirectory "entries"
39 home <- getHomeDirectory
40 templates <- allFilesIn $ home ++ "/.xyz/themes"
41 putStrLn "Enter a name for your project:"
42 projectName <- getLine
43 putStrLn "Enter short description for your project:"
44 projectDescription <- getLine
45 putStrLn $ "Which theme would you like to use?\n\n" ++ (ununlines templates)
47 writeFile "xyz.json" . encode . toJSObject $ [("name", projectName), ("description", projectDescription), ("theme", theme)]
48 putStrLn "Initialised empty project"
52 fileExists <- doesFileExist "xyz.json"
55 files <- allFilesIn "entries"
56 home <- getHomeDirectory
57 config <- readFile "xyz.json"
58 someFunc (decodeJSON config :: ProjectConfig) files >> putStrLn "Build successful"
59 else putStrLn "This does not appear to be a valid project directory"
61 ununlines :: [String] -> String
62 ununlines = intercalate "\n\n"
66 homeDir <- getHomeDirectory
67 entryName <- textPrompt "Name for this entry:"
68 video <- (fmap . fmap) (\(a,b) -> (a, b ++ ".webm"::String)) $ dependantPrompt "Video ID (leave blank to skip):" "Local video filename:"
69 entryNum <- fmap ((+1) . length) $ allFilesIn "entries"
70 stamp <- fmap round getPOSIXTime
71 videoTemplate <- readFile (homeDir ++ "/.xyz/entry-video.txt") >>= return . template . fromString
72 normalTemplate <- readFile (homeDir ++ "/.xyz/entry.txt") >>= return . template . fromString
73 let filename = "entries/" ++ (show entryNum) ++ "-" ++ (unpack . (toLower. replace " " "-") $ pack entryName) ++ ".txt"
76 Just (videoId, videoFilename) -> do
77 let tmplContext = context $ [("timestamp", fromString . show $ (stamp::Integer)), ("title", pack entryName), ("videofilename", pack $ videoFilename), ("videoid", pack videoId)]
78 let rawEntry = unpack . toStrict $ render videoTemplate tmplContext
79 writeFile filename rawEntry
80 callCommand $ "youtube-dl -f 'webm[height<1080]+bestaudio' \"https://www.youtube.com/watch?v=" ++ videoId ++ "\" -o 'build/videos/" ++ videoFilename ++ "'"
82 let tmplContext = context $ [("timestamp", fromString . show $ (stamp::Integer)), ("title", pack entryName)]
83 let rawEntry = unpack . toStrict $ render normalTemplate tmplContext
84 writeFile filename rawEntry
86 (putStrLn $ ("Created " ++ filename)) >> build
88 push <- yornPrompt "Do you want to push this entry?"
91 True -> do callCommand $ "git add . && git commit -m \"" ++ entryName ++ "\" && git push"
94 putStrLn "Thanks for using xyz!"
97 usage = putStr . ununlines $ [
98 "usage: xyz <command>",
99 "Commands:", unlines [
100 "\tinit\t\tInitialise a new site",
101 "\tbuild\t\tBuild the site",
102 "\tentry\t\tInitialise an entry"
106 parse ["init"] = init >> exitSuccess
107 parse ["build"] = continueIfValidProject build >> exitSuccess
108 parse ["entry"] = continueIfValidProject entry >> exitSuccess
109 parse [_] = usage >> exit
110 parse [] = usage >> exit
112 exit = exitWith ExitSuccess