aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--main.go10
-rw-r--r--timetask/http.go51
-rw-r--r--timetask/http_test.go2
-rw-r--r--timetask/module.go24
-rw-r--r--timetask/module_test.go50
6 files changed, 139 insertions, 2 deletions
diff --git a/TODO b/TODO
index 2065140..63d68fb 100644
--- a/TODO
+++ b/TODO
@@ -16,6 +16,8 @@ v Config (2017.06.03)
v Make `PasswordCmd` work
-- Request and list module IDs and names for a given project alias
+v Request and list module IDs and names for a given project alias (2017.06.03)
v Format float error ("700") (2017.06.03)
+
+- Move HTTP errors into http.go
diff --git a/main.go b/main.go
index 861dc8b..1521821 100644
--- a/main.go
+++ b/main.go
@@ -42,6 +42,7 @@ func main() {
)
write_config := kingpin.Flag("write-config", write_config_description).
Bool()
+ list_modules := kingpin.Flag("list-modules", "List sprints with IDs").Bool()
kingpin.Version(VERSION)
kingpin.Parse()
@@ -108,6 +109,15 @@ func main() {
os.Exit(1)
}
+ // List modules
+ if *list_modules {
+ modules, err := timetask.RequestModules(*client, time_entry)
+ kingpin.FatalIfError(err, "could not retrieve sprints")
+ fmt.Println(modules)
+
+ os.Exit(0)
+ }
+
resp, err = timetask.SubmitTimeEntry(*client, time_entry)
kingpin.FatalIfError(err, "time entry submission request failed")
diff --git a/timetask/http.go b/timetask/http.go
index 8c41b4f..575ceae 100644
--- a/timetask/http.go
+++ b/timetask/http.go
@@ -1,6 +1,9 @@
package timetask
import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
@@ -126,3 +129,51 @@ func buildSubmissionParams(time_entry TimeEntry) url.Values {
return v
}
+
+func RequestModules(
+ client http.Client,
+ time_entry TimeEntry,
+) (string, error) {
+ params := url.Values{
+ "module": {"projects"},
+ "action": {"listmodulesxref"},
+ "f_ID": {strconv.Itoa(time_entry.Project)},
+ "f_active": {"t"},
+ "f_clientID": {strconv.Itoa(time_entry.Client)},
+ "f_personID": {strconv.Itoa(time_entry.PersonID)},
+ "f_milestoneID": {""},
+ }
+ modules_url, err := url.Parse(baseURL)
+ if err != nil {
+ return "", err
+ }
+
+ modules_url.RawQuery = params.Encode()
+
+ resp, err := client.Get(modules_url.String())
+ if err != nil {
+ return "", err
+ }
+
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+ response_body := string(body)
+
+ modules, err := ModuleParseXML(response_body)
+ if err != nil {
+ return "", err
+ }
+
+ var module_buf bytes.Buffer
+ module_buf.WriteString("ID\tModule\n")
+ for _, module := range modules {
+ module_buf.WriteString(
+ fmt.Sprintf("%d\t%s\n", module.ID, module.Name),
+ )
+ }
+
+ return module_buf.String(), nil
+}
diff --git a/timetask/http_test.go b/timetask/http_test.go
index 604c3c3..36f9e4a 100644
--- a/timetask/http_test.go
+++ b/timetask/http_test.go
@@ -19,7 +19,7 @@ func init() {
func TestLogin(t *testing.T) {
t.Skip("No requests")
- response, err := Login(username, password)
+ response, _, err := Login(username, password)
if err != nil {
t.Fatal(err)
}
diff --git a/timetask/module.go b/timetask/module.go
new file mode 100644
index 0000000..4dde57a
--- /dev/null
+++ b/timetask/module.go
@@ -0,0 +1,24 @@
+package timetask
+
+import (
+ "encoding/xml"
+)
+
+type Module struct {
+ ID int `xml:"moduleid"`
+ Name string `xml:"modulename"`
+}
+
+type moduleXML struct {
+ Modules []Module `xml:"response>item"`
+}
+
+func ModuleParseXML(xml_str string) ([]Module, error) {
+ modules := moduleXML{}
+ err := xml.Unmarshal([]byte(xml_str), &modules)
+ if err != nil {
+ return nil, err
+ }
+
+ return modules.Modules, nil
+}
diff --git a/timetask/module_test.go b/timetask/module_test.go
new file mode 100644
index 0000000..cee87c5
--- /dev/null
+++ b/timetask/module_test.go
@@ -0,0 +1,50 @@
+package timetask
+
+import "testing"
+
+const modules_xml = `<?xml version="1.0" encoding="UTF-8" ?>
+<ajax-response>
+ <response type="object" id="ModuleList">
+ <item>
+ <moduleid><![CDATA[55555]]></moduleid>
+ <modulename><![CDATA[R&amp;D]]></modulename>
+ </item>
+ <item>
+ <moduleid><![CDATA[77777]]></moduleid>
+ <modulename><![CDATA[Sprint 1]]></modulename>
+ </item>
+ <item>
+ <moduleid><![CDATA[222222]]></moduleid>
+ <modulename><![CDATA[Sprint 2]]></modulename>
+ </item>
+ </response>
+</ajax-response>`
+
+func TestModuleParseXML(t *testing.T) {
+ modules, err := ModuleParseXML(modules_xml)
+ if err != nil {
+ t.Error(err)
+ }
+
+ _ = []Module{ // wanted
+ Module{
+ ID: 55555,
+ Name: "R&amp;D",
+ },
+ Module{
+ ID: 77777,
+ Name: "Sprint 1",
+ },
+ Module{
+ ID: 222222,
+ Name: "Sprint 2",
+ },
+ }
+
+ // Need a way to compare slices
+ // if modules != wanted {
+ // t.Errorf("Module parsing failed. Wanted %+v got %+v", wanted, modules)
+ // }
+
+ t.Logf("%+v\n", modules)
+}