aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.go75
-rw-r--r--list.tmpl1
-rw-r--r--project.go (renamed from projects.go)30
-rw-r--r--table.tmpl20
4 files changed, 106 insertions, 20 deletions
diff --git a/data.go b/data.go
index 8ee87a7..2184331 100644
--- a/data.go
+++ b/data.go
@@ -47,7 +47,7 @@ type Data struct {
Issues Issues
Features Issues
- Projects Projects
+ Project Project
Timestamp time.Time
Freq time.Duration
Lasterror error
@@ -73,6 +73,63 @@ func NewData(ctx context.Context, url, token string, num int) *Data {
return data
}
+func (d *Data) getProject() {
+ url := fmt.Sprintf("%s/projects/%d", d.url, d.projectId)
+ req, e := http.NewRequestWithContext(d.ctx, "GET", url, nil)
+ if nil != e {
+ d.mux.Lock()
+ defer d.mux.Unlock()
+ d.Lasterror = e
+ return
+ }
+ req.Header.Add("Authorization", d.token)
+
+ r, e := http.DefaultClient.Do(req)
+ if nil != e {
+ d.mux.Lock()
+ defer d.mux.Unlock()
+ d.Lasterror = e
+ return
+ } else if 200 != r.StatusCode {
+ d.mux.Lock()
+ defer d.mux.Unlock()
+ d.Lasterror = fmt.Errorf("Got unexpected status %s\n", r.Status)
+ return
+ }
+
+ var project Project
+ p := struct{ Projects []Project }{}
+ e = json.NewDecoder(r.Body).Decode(&p)
+
+ if len(p.Projects) < 1 {
+ e = fmt.Errorf("no project found with id", d.projectId)
+ } else {
+ // filter out obsolete versions
+ project = p.Projects[0]
+ var versions Versions
+ log.Println("found", len(project.Versions), "versions")
+ for _, v := range project.Versions {
+ v := v
+ if !v.Obsolete && !v.Released {
+ versions = append(versions, v)
+ }
+ }
+ project.Versions = versions
+ }
+
+ d.mux.Lock()
+ defer d.mux.Unlock()
+ d.Lasterror = e
+ if nil != e {
+ return
+ }
+
+ d.Timestamp = time.Now()
+ d.Project = project
+
+ fmt.Println("Got project details for", d.projectId, "with", len(d.Project.Versions), "version entries")
+}
+
const statusFilter = `status%5B%5D=10&status%5B%5D=20&status%5B%5D=30&status%5B%5D=40&status%5B%5D=50&severity%5B%5D=20`
var fields = []string{"id",
@@ -92,7 +149,7 @@ var fields = []string{"id",
"tags",
}
-func (d *Data) update() {
+func (d *Data) getIssues() {
url := fmt.Sprintf("%s/issues?project_id=%d&page_size=%d&%s&select=%s",
d.url, d.projectId, d.num, statusFilter,
strings.Join(fields, ","))
@@ -132,9 +189,11 @@ func (d *Data) update() {
// Filter issues with old target versions out
var issues = Issues{}
var features = Issues{}
+ var open = 0
for _, issue := range iss.Issues {
if issue.Resolution.Name == "open" &&
strings.Compare(d.minimumVersion, issue.TargetVersion.Name) < 0 {
+ open++
if issue.Severity.Name == "feature" {
features = append(features, issue)
} else {
@@ -144,11 +203,12 @@ func (d *Data) update() {
}
d.Issues = issues
d.Features = features
- fmt.Println("got", len(iss.Issues), "entries: ", len(features), "features and ", len(issues), "issues")
+ fmt.Println("Got", len(iss.Issues), "entries, of which", open, "are open and relevant:", len(features), "features and", len(issues), "issues")
}
func (d *Data) Loop() {
- d.update()
+ d.getProject()
+ d.getIssues()
go func() {
var ticker = time.NewTicker(d.Freq)
for range ticker.C {
@@ -157,7 +217,8 @@ func (d *Data) Loop() {
return
default:
fmt.Println("updating data")
- d.update()
+ d.getProject()
+ d.getIssues()
}
}
}()
@@ -203,6 +264,10 @@ func (d *Data) TargetVersions() (tv []string) {
return
}
+func (d *Data) VersionsByDate() VersionsByDate {
+ return VersionsByDate(d.Project.Versions)
+}
+
func (d *Data) Categories() (cs []string) {
d.mux.RLock()
defer d.mux.RUnlock()
diff --git a/list.tmpl b/list.tmpl
index 6442237..621d2e6 100644
--- a/list.tmpl
+++ b/list.tmpl
@@ -31,6 +31,7 @@ pre {
{{ $top := . }}
{{ $features := .Features }}
{{ $issues := .Issues }}
+ {{ $versions := .VersionsByDate }}
<!-- p>
{{ range $top.Tags }}
<button>{{ . }}</button>
diff --git a/projects.go b/project.go
index 50ca2f0..aca73ba 100644
--- a/projects.go
+++ b/project.go
@@ -22,8 +22,6 @@ import "time"
@author Özgür Kesim <oec-taler@kesim.org>
*/
-type Projects []Project
-
type Project struct {
Id int
Name string
@@ -33,19 +31,37 @@ type Project struct {
Enabled bool
InheritGlobal bool `json:"inherit_global"`
AccessLevel KeyVal `json:"AccessLevel"`
- Versions []Version
- Categories []Category
+ Versions Versions
+ Categories Categories
// CustomFields []any `json:"custom_fields"`
}
+type Versions []Version
type Version struct {
KeyVal
- Released bool
- Obsolete bool
- Timestamp time.Time
+ Description string
+ Released bool
+ Obsolete bool
+ Timestamp time.Time
}
+type VersionsByDate []Version
+
+func (v VersionsByDate) Len() int { return len(v) }
+func (v VersionsByDate) Less(i, j int) bool { return v[i].Timestamp.Before(v[j].Timestamp) }
+func (v VersionsByDate) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
+
+type Categories []Category
type Category struct {
KeyVal
Project KeyVal
}
+
+func (vs VersionsByDate) Get(version string) *Version {
+ for i, v := range vs {
+ if v.Name == version {
+ return &vs[i]
+ }
+ }
+ return nil
+}
diff --git a/table.tmpl b/table.tmpl
index 886d466..4f530a7 100644
--- a/table.tmpl
+++ b/table.tmpl
@@ -12,8 +12,7 @@ table {
}
th, td {
padding: 8px;
- border-bottom: 1px solid #ddd;
- border-right: 1px solid #ddd;
+ border: 1px solid #ddd;
}
td {
min-width: 10em;
@@ -25,8 +24,11 @@ th.side {
tr:hover {
background: #efe;
}
-.normal {
+details.version {
+ margin: 5px;
font-weight: normal;
+ max-width: 40em;
+ text-align: justify;
}
.feature {
background: #cde;
@@ -38,7 +40,7 @@ tr:hover {
border-radius: 5px;
padding: 8px;
}
-details {
+details.entry, details.feature {
max-width: 30em;
overflow-x: auto;
white-space: nowrap;
@@ -58,6 +60,7 @@ details {
{{ $top := . }}
{{ $features := .Features }}
{{ $issues := .Issues }}
+ {{ $versions := .VersionsByDate }}
<!--p>
{{ range $top.Tags }}
<button>{{ . }}</button>
@@ -69,10 +72,11 @@ details {
<th class="side"></th>
{{ range $top.TargetVersions }}
<th>
- <details>
- <summary>{{ . }}</summary>
- <div class="normal">
- TODO: more
+ <details class="version">
+ {{ $version := $versions.Get . }}
+ <summary><b>{{ . }}</b> ({{ $version.Timestamp.Format "02 Jan 06"}})</summary>
+ <div>
+ {{ $version.Description }}
</div>
</details>
</th>