summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolaus Gotsche <n@softwarefools.com>2018-09-05 04:10:54 +0200
committerNikolaus Gotsche <n@softwarefools.com>2018-09-05 04:10:54 +0200
commit4a4f372605d56f2241699da6a5bf8dae7eda2b86 (patch)
tree80025d8ee00a1ea37ff94b351ca720b7e2fc110e
parentd6dd3088da980467909a5a43fb393260c3ff7c93 (diff)
TOML Configuration added. texification working. outsourced some functions to my utilitys. billed tasks not yet checked
-rw-r--r--config.go129
-rw-r--r--interact.go82
-rw-r--r--main.go11
-rw-r--r--sqlite.go96
-rw-r--r--templates/_invoice.tex2
-rw-r--r--templates/_main.tex4
-rw-r--r--texify.go101
-rw-r--r--utils.go97
8 files changed, 498 insertions, 24 deletions
diff --git a/config.go b/config.go
new file mode 100644
index 0000000..e03a196
--- /dev/null
+++ b/config.go
@@ -0,0 +1,129 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ //"os"
+ "io/ioutil"
+ //"strconv"
+ "github.com/BurntSushi/toml"
+)
+
+type Config struct {
+ Database string //`toml:"database"`
+ Name string //`toml:"name"`
+ Street string //`toml:"street"`
+ Zip string //`toml:"zip"`
+ City string //`toml:"city"`
+ Country string //`toml:"country"`
+ Telefon string //`toml:"telefon"`
+ Mobile string //`toml:"mobile"`
+ Mail string //`toml:"mail"`
+ Url string //`toml:"url"`
+ Taxid string //`toml:"taxid"`
+ Bankacc string //`toml:"bankacc"`
+ Banklz string //`toml:"banklz"`
+ Bankname string //`toml:"bankname"`
+ Iban string //`toml:"iban"`
+ Bic string //`toml:"bic"`
+}
+
+var conffile string
+var config Config
+
+func init() {
+ conffile = "laboravi.config.toml"
+}
+
+func editConf() {
+ for {
+ if _, err := toml.DecodeFile(conffile, &config); err != nil {
+ //fmt.Println(err)
+ fmt.Println("Configuration file not found")
+ makeNewTOML(false)
+ }else{
+ showConfig()
+ if isSure("Is this Configuration Correct?") {
+ break
+ }else{
+ //if isSure("Enter new Configuration?"){
+ makeNewTOML(true)
+ //}else{
+ // fmt.Println("I Really Dont think I can Help You then...!")
+ //}
+ }
+ }
+ }
+}
+
+func initConf() {
+ for {
+ if _, err := toml.DecodeFile(conffile, &config); err != nil {
+ //fmt.Println(err)
+ fmt.Println("Configuration file not found")
+ makeNewTOML(false)
+ }else{
+ fmt.Println("Configuration loaded Successfully")
+ break
+ }
+ }
+}
+
+func makeNewTOML(gibts bool) {
+ if gibts {
+ fmt.Println("Editing Configuration File\nPress [Enter] to keep the Current setting")
+ }else{
+ fmt.Println("Making new Configuration File")
+
+ //arr := []string{"", "", ""}
+ //ma0 := MailAccount{"","","",0,"",""}
+ //mm0 := MassMail{"","","",arr,""}
+ //Examplenames Coming soon
+ n := ""
+ config = Config{"mytimes.db",n,n,n,n,n,n,n,n,n,n,n,n,n,n,n}
+ }
+ //fmt.Println("Whats Your Namecount\n")
+ database := getNewInput("DB File Path: ",config.Database)
+ name := getNewInput("Whats your Name?: ",config.Name)
+ street := getNewInput("Street: ",config.Street)
+ zip := getNewInput("Zip Code: ",config.Zip)
+ city := getNewInput("City: ",config.City)
+ country := getNewInput("Country: ",config.City)
+ telefon := getNewInput("Telefone number: ",config.Telefon)
+ mobile := getNewInput("Mobile number: ",config.Mobile)
+ mail := getNewInput("Email: ",config.Mail)
+ url := getNewInput("URL: ",config.Url)
+ taxid := getNewInput("Tax ID: ",config.Taxid)
+ bankname := getNewInput("Bank Name: ",config.Bankname)
+ bankacc := getNewInput("Bank Account: ",config.Bankacc)
+ banklz := getNewInput("BLZ: ",config.Banklz)
+ iban := getNewInput("IBAN: ",config.Iban)
+ bic := getNewInput("BIC: ",config.Bic)
+
+ conf := Config{database,name,street,zip,city,country,telefon,mobile,mail,url,taxid,bankacc,banklz,bankname,iban,bic}
+
+ buf := new(bytes.Buffer)
+ err = toml.NewEncoder(buf).Encode(conf)
+ if err != nil {
+ panic(err)
+ }else{
+ //fmt.Println("Conffile:\n",buf.String())
+ fmt.Println("Writing Configuration File")
+ err = ioutil.WriteFile(conffile, buf.Bytes(), 0644)
+ checkErr(err)
+ }
+
+}
+
+func showConfig() {
+ buf := new(bytes.Buffer)
+ err := toml.NewEncoder(buf).Encode(config)
+ if err != nil {
+ panic(err)
+ }else{
+ fmt.Println("Configuration:\n",buf.String())
+ //fmt.Println(config)
+ }
+}
+
+
diff --git a/interact.go b/interact.go
index f555b55..918b2a9 100644
--- a/interact.go
+++ b/interact.go
@@ -5,6 +5,7 @@ import (
"strings"
"strconv"
"fmt"
+ "time"
"github.com/abiosoft/ishell"
"github.com/fatih/color"
@@ -34,7 +35,27 @@ func interact() {
showLastProject()
},
})
-
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "config",
+ Help: "View and Edit Configuration",
+ Func: func(c *ishell.Context) {
+ //c.Print("\033[H\033[2J")
+ //c.Println(boldGreen("Start New Project"))
+ editConf()
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "show",
+ Help: "Show Current State",
+ Func: func(c *ishell.Context) {
+ //c.Print("\033[H\033[2J")
+ //c.Println(boldGreen("Start New Project"))
+ stdOut()
+ },
+ })
+
shell.AddCmd(&ishell.Cmd{
Name: "add",
Help: "Add new Customer",
@@ -319,19 +340,22 @@ func interact() {
//c.Printf("%v Tasks Selected. Totaling %.2f (h) - Dates: %s\n",count,hours,dur)
proj,cust := getProject(billprojid)
- billid := newBill(billprojid)
+ 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("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.Println("Create New Bill:",billid)
+ //c.ReadLine() //Make NEW BILL WITH ID and INV No
+ c.ShowPrompt(false)
- fullbillinfo := fmt.Sprintf("For: %s - %s - Invoice: %s\nProject: %s - Id:%v\n%v Tasks Selected. Totaling %.2f (h) - Dates: %s\nProjected Income: %.2f(€)\n",cust.company,cust.name,billid,proj.name,proj.id,count,hours,dur,hours*cust.satz)
+ 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
@@ -340,8 +364,12 @@ func interact() {
if len(restids) == 0 {
break
}
+ resttasks := getSelectedTasks(restids)
+ rcount,rhours,_ := analyzeTasks(resttasks)
+
rids,rstr := getTaskList(restids,false)
- restinfo = "Select Tasks to Group as Billitem"
+ 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)
@@ -353,9 +381,43 @@ func interact() {
}
taskids := out()
restids = removeItems(restids,taskids)
- c.Println("Full",selids,"Your choices are",taskids,"Rest:",removeItems(selids,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,hrf*cust.satz})
+ c.Print("<<Continue>>")
+ 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)
+ testid := []int{billid}
+ testbill := loadBills(testid)
+ //c.Println(testbill[0].projectname,testbill[0].items)
+ files := billTemplate(testbill[0],cust)
+ c.Println(files)
+ c.Print("<<Continue>>")
+ c.ReadLine()
+ stdOut()
}
+ c.ShowPrompt(true)
},
})
diff --git a/main.go b/main.go
index 68a2397..695d0de 100644
--- a/main.go
+++ b/main.go
@@ -17,7 +17,7 @@ var starttime,stoptime string
var projectid, edittaskid, editprojectid, editcustomerid int
var deltask int
var addcustomer bool
-var newproject, newtask, stoptask, allproj, runinter, test bool
+var newproject, newtask, stoptask, allproj, runinter, test, newconfig bool
//var red, green, yellow, cyan color
//var boldRed, boldGreen color
@@ -37,6 +37,10 @@ func init() {
"Test Some Functions")
+ flag.BoolVar(&newconfig,
+ "config",
+ false,
+ "View and Edit Configuration")
flag.BoolVar(&addcustomer,
"addcustomer",
false,
@@ -111,6 +115,7 @@ func stdOut() {
func main() {
fmt.Println("Laboravi Started")
+ initConf()
dbname := "./.mytimes.db"
if len(flag.Args())>0 {
@@ -154,7 +159,9 @@ func main() {
if runinter {
interact()
}
-
+ if newconfig {
+ editConf()
+ }
if newproject {
newProject()
os.Exit(0)
diff --git a/sqlite.go b/sqlite.go
index 79ef4a7..f51a459 100644
--- a/sqlite.go
+++ b/sqlite.go
@@ -5,7 +5,7 @@ import (
"fmt"
"time"
"os"
- "bufio"
+ //"bufio"
"strings"
"regexp"
"strconv"
@@ -42,6 +42,24 @@ type customer struct{
lastbill time.Time
}
+type billitem struct{
+ Task string
+ Time string
+ Hours float64
+ Money float64
+}
+
+type bill struct{
+ id int
+ identity string //invoice number
+ timerange string
+ project int
+ projectname string
+ date time.Time
+ paid time.Time
+ items []billitem
+}
+
var db *sql.DB
var err error
var currproject project
@@ -160,7 +178,7 @@ func newTask(proj int) {
}
}
-func newBill(proj int) (int) {
+func newBill(proj int) (int,string) {
boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
//boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
fmt.Println(boldGreen("Creating New Bill"))
@@ -173,7 +191,65 @@ func newBill(proj int) (int) {
checkErr(err)
lid,_ := answ.LastInsertId()
fmt.Println("Bill",invno,"Created with ID",lid)
- return int(lid)
+ return int(lid), invno
+}
+
+func saveBill(in bill) {
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ tasks,times,hours,moneys := items2strings(in.items)
+ fmt.Println(boldGreen("Saving Bill"),in.id)
+ stmt, err := db.Prepare("UPDATE bills SET identity = ?, timerange = ?, tasks = ?, times = ?, hours = ?, moneys = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(in.identity,in.timerange,tasks,times,hours,moneys,in.id)
+ checkErr(err)
+}
+
+func loadBills(in []int) (out []bill){
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
+ que := fmt.Sprintf("SELECT * FROM bills WHERE id IN (%s) ORDER BY project DESC",ins)
+ rows,err := db.Query(que)
+
+ var id,proj int
+ var ident,timerange string
+ var date,paid time.Time
+ var taskstr,timestr,hourstr,moneystr string
+
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id,&ident,&timerange,&proj,&taskstr,&timestr,&hourstr,&moneystr,&paid,&date)
+ checkErr(err)
+ itms := strings2items(taskstr,timestr,hourstr,moneystr)
+ prname,_ := getProjectName(proj)
+ bi := bill{id,ident,timerange,proj,prname,date,paid,itms}
+ out = append(out,bi)
+ }
+ return
+}
+func strings2items(tasks, times, hours, moneys string) (out []billitem) {
+ ta := string2StringArray(tasks,";")
+ ti := string2StringArray(times,";")
+ ho := string2FloatArray(hours,";")
+ mo := string2FloatArray(moneys,";")
+ for i,_ := range ta{
+ out = append(out,billitem{ta[i],ti[i],ho[i],mo[i]})
+ }
+ return
+}
+
+func items2strings(in []billitem) (tasks, times, hours, moneys string) {
+ var tsk,tim []string
+ var hrs,mny []float64
+ for _,item := range in {
+ tsk = append(tsk,item.Task)
+ tim = append(tim,item.Time)
+ hrs = append(hrs,item.Hours)
+ mny = append(mny,item.Money)
+ }
+ tasks = stringArray2String(tsk,";")
+ times = stringArray2String(tim,";")
+ hours = strings.Trim(strings.Replace(fmt.Sprint(hrs)," ",";",-1),"[]")
+ moneys = strings.Trim(strings.Replace(fmt.Sprint(mny)," ",";",-1),"[]")
+ return
}
func closeTaskTime(tim string) {
@@ -385,7 +461,8 @@ func analyzeTasks(in []task) (count int, hours float64, duration string) {
}
//txt := fmt.Sprintf("%s - (%v) - %.2f h",task, durstr, dur)
}
- duration = fmt.Sprintf("%v - %v",lstart.Local().Format("01.02.2006"),hstop.Local().Format("01.02.2006"))
+ duration = fmt.Sprintf("%v - %v",lstart.Local().Format("01.02."),hstop.Local().Format("01.02.2006"))
+ //duration = fmt.Sprintf("%v - %v",lstart.Local().Format("01.02.2006"),hstop.Local().Format("01.02.2006"))
return
}
@@ -728,7 +805,7 @@ func deleteTask(id int) {
fmt.Println(boldGreen("Delete Task", id))
dur := float64(stop.Sub(start))/(1000000000*60*60)
fmt.Printf("%v: %v (%v-%v) - %.2f h\n",prj,task,start.Local().Format("2006 Mon Jan _2 15:04"),stop.Local().Format("15:04"),dur)
- if isSure() {
+ if isSure("Are You Sure?") {
stmt, err := db.Prepare("DELETE FROM timetable WHERE id = ?")
checkErr(err)
_, err = stmt.Exec(id)
@@ -991,6 +1068,7 @@ func isTime(in string) bool {
return match
}
+/*
func getInput(quest string) string {
fmt.Print(quest)
in := bufio.NewReader(os.Stdin)
@@ -998,8 +1076,9 @@ func getInput(quest string) string {
line = strings.TrimSuffix(line, "\n")
checkErr(err)
return line
-}
+}*/
+/*
func isSure() bool {
fmt.Print("Are You Sure ? (type 'yes' to confirm) : ")
in := bufio.NewReader(os.Stdin)
@@ -1012,7 +1091,7 @@ func isSure() bool {
} else {
return false
}
-}
+}*/
func isElement(some int, group []int) (bool) {
for _,e := range group {
@@ -1033,8 +1112,9 @@ func removeItems(master, rem []int) ([]int) {
return out
}
+/*
func checkErr(err error) {
if err != nil {
panic(err)
}
-}
+}*/
diff --git a/templates/_invoice.tex b/templates/_invoice.tex
index ae899fc..cb1d9f7 100644
--- a/templates/_invoice.tex
+++ b/templates/_invoice.tex
@@ -1,6 +1,6 @@
\ProjectTitle{EinBeliebeigerTitel} % Muss gesetzt bleiben, scheint nirgends auf
[[range .]]
-\FeeTwo{[[.Task]]}{[[.Timeframe]]}{[[.Hours]]}{[[.Price]]}
+\FeeTwo{[[.Task]]}{[[.Time]]}{[[.Hours]]}{[[.Money]]}
[[end]]
% Auslagen
diff --git a/templates/_main.tex b/templates/_main.tex
index b07b221..8fd1eb2 100644
--- a/templates/_main.tex
+++ b/templates/_main.tex
@@ -15,7 +15,7 @@
\renewcommand{\familydefault}{\sfdefault}
% include meta data
-\include{_data}
+\include{[[.Data]]}
\setkomavar{fromname}{\senderName}
\setkomavar{fromaddress}{\senderStreet \\ \senderZIP \ \senderCity}
@@ -70,7 +70,7 @@
\fcolorbox{lightgray}{lightgray}{\parbox{\textwidth}{\large{Projekt: \textbf{\invoiceTitle}}}}
\begin{invoice}{Euro}{0}
- \input{_invoice}
+ \input{[[.Invoice]]}
\end{invoice}
\ps Im ausgewiesenen Betrag ist gemäß § 19 UStG keine Umsatzsteuer
enthalten.
diff --git a/texify.go b/texify.go
index 01ccd8f..71a9988 100644
--- a/texify.go
+++ b/texify.go
@@ -1,6 +1,7 @@
package main
import (
+ "fmt"
"os"
"text/template"
)
@@ -8,29 +9,40 @@ import (
type FeeItem struct{
Task string
Timeframe string
- Hours int
+ Hours float64
Price float64
}
+type Filenames struct{
+ Data string
+ Invoice string
+ Main string
+}
+
type Data struct {
InvDate string
WorkDate string
InvNo string
ProjName string
+
CustComp string
CustName string
CustStr string
CustZip string
CustCity string
+ CustCountry string
+
TaxID string
MyName string
MyStr string
MyZip string
MyCity string
+ MyCountry string
MyTel string
MyMob string
MyMail string
MyUrl string
+
BankNum string
BankLZ string
BankName string
@@ -38,6 +50,91 @@ type Data struct {
Bic string
}
+func billTemplate(billdata bill, cust customer) (Filenames) {
+ billid := billdata.id
+ custr,cuzip,cucity,cucou := "","","",""
+ addr := string2StringArray(cust.address,";")
+ for i,a := range addr {
+ switch i {
+ case 0:
+ custr=a
+ case 1:
+ cuzip=a
+ case 2:
+ cucity=a
+ case 3:
+ cucou=a
+ default:
+ break
+ }
+ }
+ dat := Data{billdata.date.UTC().Format("2006-01-02"),
+ billdata.timerange,
+ billdata.identity,
+ billdata.projectname,
+
+ cust.company,
+ cust.name,
+ custr,
+ cuzip,
+ cucity,
+ cucou,
+
+ config.Taxid,
+ config.Name,
+ config.Street,
+ config.Zip,
+ config.City,
+ config.Country,
+ config.Telefon,
+ config.Mobile,
+ config.Mail,
+ config.Url,
+
+ config.Bankacc,
+ config.Banklz,
+ config.Bankname,
+ config.Iban,
+ config.Bic,
+ }
+
+ inv := billdata.items
+
+ filenamedata := fmt.Sprintf("%v_data",billid)
+ filenameinv := fmt.Sprintf("%v_invoice",billid)
+ filenamemain := fmt.Sprintf("outtex/%v_main.tex",billid)
+ fnames := Filenames{filenamedata,filenameinv,filenamemain}
+
+ //Parse Templates
+ tmpl, err := template.New("invoice").Delims("[[","]]").ParseGlob("templates/*.tex")
+ checkErr(err)
+ filenamedata = fmt.Sprintf("outtex/%v_data.tex",billid)
+ filenameinv = fmt.Sprintf("outtex/%v_invoice.tex",billid)
+ filenamemain = fmt.Sprintf("outtex/%v_main.tex",billid)
+
+ //Open File
+ datf, err := os.Create(filenamedata)
+ checkErr(err)
+ invf, err := os.Create(filenameinv)
+ checkErr(err)
+ maif, err := os.Create(filenamemain)
+ checkErr(err)
+ defer datf.Close()
+ defer invf.Close()
+ defer maif.Close()
+
+ //Execute Template
+ //err = tmpl.ExecuteTemplate(os.Stdout, "invoice.tex", td)
+ err = tmpl.ExecuteTemplate(datf, "_data.tex", dat)
+ checkErr(err)
+ err = tmpl.ExecuteTemplate(invf, "_invoice.tex", inv)
+ checkErr(err)
+ err = tmpl.ExecuteTemplate(maif, "_main.tex", fnames)
+ checkErr(err)
+
+ return fnames
+}
+
func tmpltest() {
//Sampledata
@@ -50,11 +147,13 @@ func tmpltest() {
"Fakestreet 123",
"6996",
"Busenhausen",
+ "Tittania",
"6575-6544",
"Meinam Sauluschtig",
"Saubastrasse 86",
"1111",
"Nicetown",
+ "Niceland",
"+43 (1) 655 555 23",
"+43 (0) 650 555 32",
"Meinam@sauluscht.ig",
diff --git a/utils.go b/utils.go
new file mode 100644
index 0000000..c94f94b
--- /dev/null
+++ b/utils.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+ "fmt"
+ "bufio"
+ "os"
+ "strings"
+ "strconv"
+ "runtime"
+)
+
+func isSure(quest string) bool {
+ fmt.Printf("%s (type 'y/Y/yes' to confirm) : ",quest)
+ in := bufio.NewReader(os.Stdin)
+ line, err := in.ReadString('\n')
+ if(runtime.GOOS == "windows"){
+ line = strings.TrimSuffix(line, "\r\n") //for Windows
+ }else{
+ line = strings.TrimSuffix(line, "\n")
+ }
+ checkErr(err)
+
+ if ( line == "yes" || line == "y" || line == "Y") {
+ return true
+ } else {
+ return false
+ }
+}
+
+func checkErr(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+func getInput(quest string) string {
+ fmt.Print(quest)
+ in := bufio.NewReader(os.Stdin)
+ line, err := in.ReadString('\n')
+ if(runtime.GOOS == "windows"){
+ line = strings.TrimSuffix(line, "\r\n") //for Windows
+ }else{
+ line = strings.TrimSuffix(line, "\n")
+ }
+ checkErr(err)
+ return line
+}
+
+func getNewInput(quest,old string) string {
+ if old != "" {
+ fmt.Println("Current:",old)
+ }
+ fmt.Print(quest)
+ in := bufio.NewReader(os.Stdin)
+ line, err := in.ReadString('\n')
+ if(runtime.GOOS == "windows"){
+ line = strings.TrimSuffix(line, "\r\n") //for Windows
+ }else{
+ line = strings.TrimSuffix(line, "\n")
+ }
+ checkErr(err)
+ if line == "" {
+ return old
+ }else{
+ return line
+ }
+}
+
+func stringArray2String(in []string, delim string) (string) {
+ var out string
+ for i,a := range in {
+ if i==0 {
+ out=a
+ }else{
+ out=fmt.Sprintf("%s%s%s",out,delim,a)
+ }
+ }
+ return out
+}
+
+func string2FloatArray(in string,delim string)(out []float64) {
+ read := strings.Split(in,delim)
+ for _,s := range read{
+ fs,err := strconv.ParseFloat(s,64)
+ checkErr(err)
+ out = append(out,fs)
+ }
+ return
+}
+
+func string2StringArray(in string,delim string)(out []string) {
+ read := strings.Split(in,delim)
+ for _,s := range read{
+ out = append(out,s)
+ }
+ return
+}