~emersion/drmdb

82877980d6b182124dfac52f461a859815523488 — Simon Ser 2 years ago 8f35224
Print other snapshots on device page
2 files changed, 85 insertions(+), 16 deletions(-)

M public/device.html
M server.go
M public/device.html => public/device.html +37 -1
@@ 9,7 9,12 @@
	<a href="/">Back to index</a>
</p>

<h2>Raw data</h2>
<ul>
	<li><a href="#tree">Latest snapshot</a></li>
	<li><a href="#alt-devices">Other snapshots ({{len .AltDevices}})</a></li>
</ul>

<h2 id="tree">Latest snapshot</h2>

{{define "tree"}}
	<li>{{.Text}}


@@ 28,3 33,34 @@
	{{template "tree" .}}
	{{end}}
</ul>

<h2 id="alt-devices">Other snapshots</h2>

{{if eq (len .AltDevices) 0}}
<p>No other snapshots available</p>
{{else}}
<table>
	<thead>
		<tr>
			<th>Key</th>
			<th>Driver</th>
			<th>Kernel</th>
		</tr>
	</thead>
	<tbody>
		{{range .AltDevices}}
		<tr>
			<td class="pre">
				<a href="/devices/{{.Key}}">{{.Key}}</a>
			</td>
			<td>{{.Driver.Name}} {{.Driver.Version.String}}</td>
			{{if .Driver.Kernel.SysName}}
			<td>{{.Driver.Kernel.SysName}} {{.Driver.Kernel.Release}}</td>
			{{else}}
			<td class="status-unknown">?</td>
			{{end}}
		</tr>
		{{end}}
	</tbody>
</table>
{{end}}

M server.go => server.go +48 -15
@@ 7,6 7,7 @@ import (
	"io"
	"net/http"
	"os"
	"sort"
	"strings"

	"git.sr.ht/~emersion/drmdb/drmtree"


@@ 51,6 52,11 @@ type deviceData struct {
	Driver  string
}

type altDeviceData struct {
	Key    string
	Driver *drmtree.Driver
}

func walkProps(props drmtree.PropertyMap, obj drm.AnyID, f func(drm.AnyID, string, *drmtree.Property) error) error {
	for name, prop := range props {
		if err := f(obj, name, &prop); err != nil {


@@ 79,21 85,23 @@ func walkNodeProps(n *drmtree.Node, f func(drm.AnyID, string, *drmtree.Property)
	return nil
}

func driverLess(a *drmtree.Driver, b *drmtree.Driver) bool {
	if a.Version.Less(&b.Version) {
		return true
	}
	// Linux is the upstream
	if b.Kernel.SysName == "Linux" && a.Kernel.SysName != "Linux" {
		return true
	}
	return version.Compare(a.Kernel.Release, b.Kernel.Release, "<=")
}

func walkLatestDriver(fn func(n *drmtree.Node) error) error {
	latest := make(map[string]*drmtree.Node)
	err := walk(func(k string, n *drmtree.Node) error {
		other, ok := latest[n.Driver.Name]
		if ok {
			if n.Driver.Version.Less(&other.Driver.Version) {
				return nil
			}
			// Linux is the upstream
			if other.Driver.Kernel.SysName == "Linux" && n.Driver.Kernel.SysName != "Linux" {
				return nil
			}
			if version.Compare(n.Driver.Kernel.Release, other.Driver.Kernel.Release, "<=") {
				return nil
			}
		if ok && driverLess(n.Driver, other.Driver) {
			return nil
		}
		latest[n.Driver.Name] = n
		return nil


@@ 261,14 269,39 @@ func New() *echo.Echo {
		if raw {
			return c.JSON(http.StatusOK, n)
		} else {
			var altDevices []altDeviceData
			err := walk(func(k string, other *drmtree.Node) error {
				if k == key {
					return nil
				}
				if other.Device.BusType != n.Device.BusType || other.Device.BusID() != n.Device.BusID() {
					return nil
				}

				altDevices = append(altDevices, altDeviceData{
					Key: k,
					Driver: n.Driver,
				})
				return nil
			})
			if err != nil {
				return err
			}

			sort.Slice(altDevices, func(i, j int) bool {
				a, b := altDevices[i], altDevices[j]
				return !driverLess(a.Driver, b.Driver)
			})

			tf := treefmt.NewMemoryFormatter()
			n.FormatTree(tf)

			return c.Render(http.StatusOK, "device.html", struct {
				Key  string
				Node *drmtree.Node
				Tree []treefmt.Memory
			}{key, n, tf.Tree()})
				Key        string
				Node       *drmtree.Node
				Tree       []treefmt.Memory
				AltDevices []altDeviceData
			}{key, n, tf.Tree(), altDevices})
		}
	})