aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.go36
-rw-r--r--timetask/fields.go3
-rw-r--r--timetask/http.go206
-rw-r--r--timetask/profile.go5
-rw-r--r--timetask/time_entry.go63
5 files changed, 161 insertions, 152 deletions
diff --git a/main.go b/main.go
index ccdcaed..3a343b5 100644
--- a/main.go
+++ b/main.go
@@ -2,9 +2,10 @@ package main
import (
// "fmt"
- // "io/ioutil"
+ "io/ioutil"
"log"
// "os"
+ "time"
"github.com/teddywing/timetasker/timetask"
@@ -14,8 +15,9 @@ import (
type Config struct {
Auth struct {
Username string
- PasswordCmd string
+ PasswordCmd string `toml:"password_cmd"`
}
+ Profile timetask.Profile
Projects map[string]timetask.Project
}
@@ -24,6 +26,36 @@ var config Config
func main() {
loadConfig()
+ resp, client, err := timetask.Login(
+ config.Auth.Username,
+ config.Auth.PasswordCmd,
+ )
+ if err != nil {
+ log.Fatalln(err)
+ }
+ log.Printf("%+v\n", resp)
+
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ log.Println(string(body))
+
+ time_entry := timetask.NewTimeEntry(
+ config.Profile,
+ config.Projects["example"],
+ time.Now(),
+ 7,
+ "timetasker test",
+ )
+ resp, err = timetask.SubmitTimeEntry(*client, time_entry)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ log.Printf("%+v\n", resp)
+
+ defer resp.Body.Close()
+ body, err = ioutil.ReadAll(resp.Body)
+ log.Println(string(body))
+
// if len(os.Args) == 1 {
// fmt.Println("Not enough arguments")
// os.Exit(1)
diff --git a/timetask/fields.go b/timetask/fields.go
index da2b37d..9f7aa99 100644
--- a/timetask/fields.go
+++ b/timetask/fields.go
@@ -21,8 +21,7 @@ type Project struct {
Project int
Module int
Task int
- WorkType int
- Time int
+ WorkType int `toml:"work_type"`
Billable bool
}
diff --git a/timetask/http.go b/timetask/http.go
index 94a1597..736fcfb 100644
--- a/timetask/http.go
+++ b/timetask/http.go
@@ -6,21 +6,27 @@ import (
"net/http"
"net/http/cookiejar"
"net/url"
- // "strconv"
+ "strconv"
// "strings"
"golang.org/x/net/publicsuffix"
)
-func Login(username, password string) (resp *http.Response, err error) {
+var baseURL string = "https://af83.timetask.com/index.php"
+
+func Login(username, password string) (
+ resp *http.Response,
+ client *http.Client,
+ err error,
+) {
cookies, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
if err != nil {
- return nil, err
+ return nil, nil, err
}
- client := http.Client{Jar: cookies}
+ client = &http.Client{Jar: cookies}
resp, err = client.PostForm(
- "https://af83.timetask.com/index.php",
+ baseURL,
url.Values{
"module": {"people"},
"action": {"loginsubmit"},
@@ -30,112 +36,94 @@ func Login(username, password string) (resp *http.Response, err error) {
},
)
if err != nil {
+ return resp, client, err
+ }
+
+ return resp, client, err
+}
+
+func SubmitTimeEntry(
+ client http.Client,
+ time_entry TimeEntry,
+) (resp *http.Response, err error) {
+ values := buildSubmissionParams(time_entry)
+
+ values.Set("module", "time")
+ values.Set("action", "submitmultipletime")
+
+ resp, err = client.PostForm(
+ baseURL,
+ values,
+ )
+ if err != nil {
return resp, err
}
- return resp, err
+ return resp, nil
}
-// func SubmitTimeEntries(fields Fields, time_entries []TimeEntry) (resp *http.Response, err error) {
-// v := buildSubmissionParams(fields, time_entries)
-//
-// v.Set("module", "time")
-// v.Set("action", "submitmultipletime")
-//
-// return nil, nil
-// }
-//
-// func buildSubmissionParams(fields Fields, time_entries []TimeEntry) url.Values {
-// v := url.Values{}
-// entry_indexes := []string{}
-//
-// for i, entry := range time_entries {
-// entry_indexes = append(entry_indexes, strconv.Itoa(i))
-//
-// client, err := fields.ClientByName(entry.Client)
-// if err != nil {
-// log.Panic(err)
-// }
-//
-// project, err := client.ProjectByName(entry.Project)
-// if err != nil {
-// log.Panic(err)
-// }
-//
-// module, err := project.ModuleByName(entry.Module)
-// if err != nil {
-// log.Panic(err)
-// }
-//
-// task, err := project.TaskByName(entry.Task)
-// if err != nil {
-// log.Panic(err)
-// }
-//
-// work_type, err := project.WorkTypeByName(entry.WorkType)
-// if err != nil {
-// log.Panic(err)
-// }
-//
-// var billable string
-// if entry.Billable {
-// billable = "t"
-// } else {
-// billable = "f"
-// }
-//
-// v.Set(
-// fmt.Sprintf("f_personID%d", i),
-// strconv.Itoa(fields.PersonID),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_clientID%d", i),
-// strconv.Itoa(client.ID),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_projectID%d", i),
-// strconv.Itoa(project.ID),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_moduleID%d", i),
-// strconv.Itoa(module.ID),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_taskID%d", i),
-// strconv.Itoa(task.ID),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_worktypeID%d", i),
-// strconv.Itoa(work_type.ID),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_date%d", i),
-// entry.Date.Format("02/01/06"), // day/month/year
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_time%d", i),
-// strconv.Itoa(entry.Time),
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_billable%d", i),
-// billable,
-// )
-//
-// v.Set(
-// fmt.Sprintf("f_description%d", i),
-// entry.Description,
-// )
-// }
-//
-// v.Set("f_entryIndexes", strings.Join(entry_indexes, ","))
-//
-// return v
-// }
+
+func buildSubmissionParams(time_entry TimeEntry) url.Values {
+ v := url.Values{}
+
+ v.Set(
+ "f_personID0",
+ strconv.Itoa(time_entry.PersonID),
+ )
+
+ v.Set(
+ "f_clientID0",
+ strconv.Itoa(time_entry.Client),
+ )
+
+ v.Set(
+ "f_projectID0",
+ strconv.Itoa(time_entry.Project),
+ )
+
+ v.Set(
+ "f_moduleID0",
+ strconv.Itoa(time_entry.Module),
+ )
+
+ v.Set(
+ "f_taskID0",
+ strconv.Itoa(time_entry.Task),
+ )
+
+ v.Set(
+ "f_worktypeID0",
+ strconv.Itoa(time_entry.WorkType),
+ )
+
+ v.Set(
+ "f_date0",
+ time_entry.Date.Format("02/01/06"), // day/month/year
+ )
+
+ v.Set(
+ "f_time0",
+ strconv.Itoa(time_entry.Time),
+ )
+
+ var billable string
+ if time_entry.Billable {
+ billable = "t"
+ } else {
+ billable = "f"
+ }
+
+ v.Set(
+ "f_billable0",
+ billable,
+ )
+
+ v.Set(
+ "f_description0",
+ time_entry.Description,
+ )
+
+ v.Set("f_entryIndexes", "0")
+
+ return v
+}
diff --git a/timetask/profile.go b/timetask/profile.go
new file mode 100644
index 0000000..9267ee6
--- /dev/null
+++ b/timetask/profile.go
@@ -0,0 +1,5 @@
+package timetask
+
+type Profile struct {
+ PersonID int `toml:"person_id"`
+}
diff --git a/timetask/time_entry.go b/timetask/time_entry.go
index 17a8e0c..161de3e 100644
--- a/timetask/time_entry.go
+++ b/timetask/time_entry.go
@@ -3,50 +3,35 @@ package timetask
import "time"
type TimeEntry struct {
- Client string
- Project string
- Module string
- Task string
- WorkType string `yaml:"work_type"`
+ PersonID int
+ Client int
+ Project int
+ Module int
+ Task int
+ WorkType int
Date time.Time
Time int
Billable bool
Description string
}
-// Parse date string into a real date
-func (te *TimeEntry) UnmarshalYAML(unmarshal func(interface{}) error) error {
- var auxiliary struct {
- Client string
- Project string
- Module string
- Task string
- WorkType string `yaml:"work_type"`
- Date string
- Time int
- Billable bool
- Description string
+func NewTimeEntry(
+ profile Profile,
+ project Project,
+ date time.Time,
+ time int,
+ description string,
+) TimeEntry {
+ return TimeEntry{
+ PersonID: profile.PersonID,
+ Client: project.Client,
+ Project: project.Project,
+ Module: project.Module,
+ Task: project.Task,
+ WorkType: project.WorkType,
+ Date: date,
+ Time: time,
+ Billable: project.Billable,
+ Description: description,
}
-
- err := unmarshal(&auxiliary)
- if err != nil {
- return err
- }
-
- date, err := time.Parse("2006-01-02", auxiliary.Date)
- if auxiliary.Date != "" && err != nil {
- return err
- }
-
- te.Client = auxiliary.Client
- te.Project = auxiliary.Project
- te.Module = auxiliary.Module
- te.Task = auxiliary.Task
- te.WorkType = auxiliary.WorkType
- te.Date = date
- te.Time = auxiliary.Time
- te.Billable = auxiliary.Billable
- te.Description = auxiliary.Description
-
- return nil
}