package main import ( "os" "strings" "strconv" "fmt" "time" "github.com/abiosoft/ishell" "github.com/fatih/color" ) func interact() { stdOut() shell := ishell.New() //fmt.Println(os.Args) //cyan := color.New(color.FgCyan).SprintFunc() //yellow := color.New(color.FgYellow).SprintFunc() green := color.New(color.FgGreen).SprintFunc() boldBlue := color.New(color.FgBlue, color.Bold).SprintFunc() boldRed := color.New(color.FgRed, color.Bold).SprintFunc() boldMag := color.New(color.FgMagenta, color.Bold).SprintFunc() boldCyan := color.New(color.FgCyan, color.Bold).SprintFunc() boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc() boldYell := color.New(color.FgYellow, color.Bold).SprintFunc() promptcol := boldBlue // display info. shell.Println("Starting interactive Shell") shell.SetPrompt(promptcol(">>>")) shell.AddCmd(&ishell.Cmd{ Name: "new", Help: "Start new Project", LongHelp: "If no Task is currently running a new project will be added to database and activated", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) newProject() showLastProject() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "config", Help: "View and Edit Configuration", LongHelp: "Contains the location of the database file and the Personal Data needed for billing", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) editConf() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "status", Help: "Show Current Project and Tasks", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) stdOut() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "add", Help: "Add new Customer", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) addCustomer() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "startnow", Help: "Start a new Task immediately", Func: func(c *ishell.Context) { //c.Println(boldGreen("New Task")) newTask(currproject.id) stdOut() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "stopnow", Help: "Stop the currently Open Task immediately", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Stoping Task",opentask.id)) closeTask() stdOut() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "deletebill", Help: " Delete a Bill with the following id", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ //c.Println(boldGreen("Opening Project",argi)) deleteBill(argi) stdOut() }else{ c.Println(boldRed(arg,"is not a valid id!")) } }else{ c.Println(boldRed("deletetask - Please enter an id")) showLastBills(0) } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "deletetask", Help: " Delete a Task with the following id", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ //c.Println(boldGreen("Opening Project",argi)) deleteTask(argi) stdOut() }else{ c.Println(boldRed(arg,"is not a valid id!")) } }else{ c.Println(boldRed("deletetask - Please enter an id")) allProjects() } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "project", Help: " Open a Project of the following id", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ //c.Println(boldGreen("Opening Project",argi)) setProject(argi) stdOut() }else{ c.Println(boldRed(arg,"is not a valid id!")) } }else{ c.Println(boldRed("project - Please enter an id")) allProjects() } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "edittask", Help: " Edit a Task of the following id", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ //c.Println(boldGreen("Editing Task",argi)) editTask(argi) //stdOut() }else{ c.Println(boldRed(arg,"is not a valid id!")) } }else{ c.Println(boldRed("edittask - Please enter an id")) } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "editproject", Help: " Edit the Project of the following id", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ editProject(argi) allProjects() //stdOut() }else{ c.Println(boldRed(arg,"is not a valid id!")) } }else{ c.Println(boldRed("editproject - Please enter an id")) allProjects() } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "editcustomer", Help: " Edit the Customer of the following id", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ //c.Println(boldGreen("Edit Project",argi)) editCustomer(argi) allCustomers() //stdOut() }else{ c.Println(boldRed(arg,"is not a valid id!")) } }else{ c.Println(boldRed("editcustomer - Please enter an id")) allCustomers() } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "start", Help: " - Start Task at a specific Time 'YYYY-MM-DD HH:MM' Or 'HH:MM'", Func: func(c *ishell.Context) { arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") //c.Println(boldGreen("Start Project at",arg)) newTaskTime(currproject.id,arg) // editProject(argi) stdOut() }else{ c.Println(boldRed("start - Please enter a Datetime")) } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "stop", Help: " - Stop Open Task at a specific Time 'YYYY-MM-DD HH:MM' Or 'HH:MM'", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") //c.Println(boldGreen("Stop Task at",arg)) closeTaskTime(arg) stdOut() }else{ c.Println(boldRed("stop - Please enter a Datetime")) } c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "all", Help: "Show all Projects", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) //c.ClearScreen() //c.Println(boldBlue(">> All Projects\n")) allProjects() stdOut() c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "allbills", Help: "Show all Bills", Func: func(c *ishell.Context) { //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) //c.Println(boldBlue(">> All Bills\n")) showLastBills(0) c.Println(promptcol("______________________")) }, }) shell.AddCmd(&ishell.Cmd{ Name: "showbills", Help: " - Show the last n bills", Func: func(c *ishell.Context) { //c.ClearScreen() arg := "none" if len(c.Args) > 0 { arg = strings.Join(c.Args, " ") argi,err := strconv.Atoi(arg) if err == nil{ showLastBills(argi) }else{ c.Println(boldRed(arg,"is not a valid integer!")) } }else{ c.Println(boldRed("showbills - Please enter an integer")) } //c.Print("\033[H\033[2J") //c.Println(boldGreen("Start New Project")) //stdOut() c.Println(promptcol("______________________")) }, }) /* shell.AddCmd(&ishell.Cmd{ Name: "color", Help: "color print", Func: func(c *ishell.Context) { c.Print(cyan("cyan\n")) c.Print(green("greencyan\n")) c.Println(yellow("yellow")) c.Printf("%s\n", boldRed("bold red")) }, }) // multiple choice shell.AddCmd(&ishell.Cmd{ Name: "choice", Help: "multiple choice prompt", Func: func(c *ishell.Context) { choice := c.MultiChoice([]string{ "Golangers", "Go programmers", "Gophers", "Goers", }, "What are Go programmers called ?") if choice == 2 { c.Println("You got it!") } else { c.Println("Sorry, you're wrong.") } }, }) // multiple choice shell.AddCmd(&ishell.Cmd{ Name: "checklist", Help: "checklist prompt", Func: func(c *ishell.Context) { languages := []string{"Python", "Go", "Haskell", "Rust"} choices := c.Checklist(languages, "What are your favourite programming languages ?", nil) out := func() (c []string) { for _, v := range choices { c = append(c, languages[v]) } return } c.Println("Your choices are", strings.Join(out(), ", ")) }, }) */ // Prompt Color shell.AddCmd(&ishell.Cmd{ Name: "colorprompt", Help: "Select the Color of the prompt", Func: func(c *ishell.Context) { choice := c.MultiChoice([]string{ boldMag("Magenta"), boldBlue("Blue"), boldCyan("Cyan"), boldGreen("Green"), boldYell("Yellow"), boldRed("Red"), }, "What Color should the Prompt be?") switch choice { case 0: c.SetPrompt(boldMag(">>>")) promptcol=boldMag case 1: c.SetPrompt(boldBlue(">>>")) promptcol=boldBlue case 2: c.SetPrompt(boldCyan(">>>")) promptcol=boldCyan case 3: c.SetPrompt(boldGreen(">>>")) promptcol=boldGreen case 4: c.SetPrompt(boldYell(">>>")) promptcol=boldYell case 5: c.SetPrompt(boldRed(">>>")) promptcol=boldRed } c.Println(promptcol("As You Wish!")) c.Println(promptcol("______________________")) }, }) // Gather Tasks For Bills shell.AddCmd(&ishell.Cmd{ Name: "bill", Help: "Select Tasks to be billed", Func: func(c *ishell.Context) { nix := []int{0} ids,str := getTaskList(nix,true) choices := c.Checklist(str, "What Tasks do you want to bill ?", nil) out := func() (c []int) { for _, v := range choices { c = append(c, ids[v]) } return } selids := out() //bids,str2 := getTaskList(selids,false) //c.Println(bids,str2) c.Println(len(selids),"Tasks Selected") if len(selids) == 0 { return } multicust, multiproj,projids := checkCustomerProjects(selids) // CHECK IF ONLY ONE CUSTOMER billprojid := 0 if multicust { c.Println(boldRed("Cannot Write One Bill to multiple Customers! Please Select different Tasks")) }else{ // CHECK IF ONLY ONE PROJECT ELSE CHOOSE ONE if multiproj { prid,prstr :=getProjectList(projids) sel := c.MultiChoice(prstr, "What Project Should be Billed ?") billprojid = prid[sel] }else{ billprojid = projids[0] } seltasks := getSelectedTasks(selids) count,hours,dur := analyzeTasks(seltasks) //c.Printf("%v Tasks Selected. Totaling %.2f (h) - Dates: %s\n",count,hours,dur) proj,cust := getProject(billprojid) if cust.id == 0 { c.Println(boldRed("Customer ",cust.company," with id ",cust.id," Cannot be billed. Please move ",proj.name," to a valid Customer")) return } billid,billident := newBill(billprojid) //prs,cus := getProjectName(billprojid) //c.Println("For",cust.company,"-",cust.name) //c.Println("Project:",proj.name,"- ID:",proj.id) //c.Println("Projected Income:",hours*cust.satz,"€") //c.Println("Create New Bill:",billid) //c.ReadLine() //Make NEW BILL WITH ID and INV No c.ShowPrompt(false) fullbillinfo := fmt.Sprintf("For: %s - %s - %.2f(€/h) - Invoice: %s Id:%v\nProject: %s - Id:%v\n%v Tasks Selected. Totaling %.2f (h) - Dates: %s\nProjected Income: %.2f(€)\n",cust.company,cust.name,cust.satz,billident,billid,proj.name,proj.id,count,hours,dur,hours*cust.satz) sep := "-------------------------\n" restinfo := "Here some Info about the rest" restids := selids var allitems []billitem //allaccounted := false //resttasks := seltasks //SELECT SUBSET AND NAME BILLITEM //c.clear()//Println(some,"Str2:",str2) for { if len(restids) == 0 { break } resttasks := getSelectedTasks(restids) rcount,rhours,_ := analyzeTasks(resttasks) rids,rstr := getTaskList(restids,false) qu := "Select Tasks to Group as Billitem" restinfo = fmt.Sprintf("%v Tasks Left, Total %.2f(h)\n%s",rcount,rhours,qu) pre := fmt.Sprintf("%s%s%s",fullbillinfo,sep,restinfo) choices2 := c.Checklist(rstr,pre,nil) out = func() (c []int) { for _, v := range choices2 { c = append(c, rids[v]) } return } taskids := out() restids = removeItems(restids,taskids) if len(taskids)>0 { ittasks := getSelectedTasks(taskids) itcount,ithours,itdur := analyzeTasks(ittasks) c.Printf("\n%v Tasks Selected, Total %.2f(h), Date: %s\n",itcount,ithours,itdur) c.ShowPrompt(false) c.Print("Name your Task for the Bill: ") tsk := c.ReadLine() var hrf float64 for { c.Print("How Many Hours: ") hr := c.ReadLine() hrf,err = strconv.ParseFloat(hr,64) if err != nil { c.Println(hr,boldRed("can not be Parsed as a Float."),"Try a shape of X.X") }else{break} } c.Printf("%T %v - %T %v\n",tsk,tsk,hrf,hrf) allitems = append(allitems,billitem{tsk,itdur,hrf,Round(hrf*cust.satz,5)}) c.Print("<>") c.ReadLine() //c.ShowPrompt(true) } } c.Println(green("Bill Completed")) fullbill := bill{billid,billident,dur,proj.id,proj.name,time.Time{},time.Time{},allitems} saveBill(fullbill) checkTasks(selids,billid) c.ProgressBar().Indeterminate(true) c.ProgressBar().Start() testid := []int{billid} testbill := loadBills(testid) //c.Println(testbill[0].projectname,testbill[0].items) files := billTemplate(testbill[0],cust) c.Println(files) err = runLatex(files.Main,testbill[0].identity) c.ProgressBar().Stop() if err== nil { c.Println("Finished without Errors") }else{ c.Println("Finished with error:",err) } c.Print("<>") c.ReadLine() stdOut() } c.Println(promptcol("______________________")) c.ShowPrompt(true) }, }) //shell.Run() // teardown //shell.Close() // when started with "exit" as first argument, assume non-interact ive execution if len(os.Args) > 1 { args := removeStringFromArray(os.Args[1:],"-file",1) //fmt.Println(args) shell.Process(args...) } else { //start shell shell.Run() // teardown shell.Close() } }