Files
asciinema/api/api.go

106 lines
2.1 KiB
Go
Raw Normal View History

2014-08-03 19:50:39 +02:00
package api
import (
2014-11-02 19:04:19 +01:00
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
2014-08-03 19:50:39 +02:00
"io"
"os"
2014-11-02 19:04:19 +01:00
"time"
2014-08-03 19:50:39 +02:00
)
2014-11-02 19:04:19 +01:00
type Frame struct {
Delay float64
Data []byte
}
2014-08-03 19:50:39 +02:00
type Api interface {
2014-11-02 19:04:19 +01:00
CreateAsciicast([]Frame, time.Duration, int, int, string, string) (string, error)
2014-08-03 19:50:39 +02:00
}
2014-08-03 20:48:48 +02:00
func New(url, token string) *AsciinemaApi {
return &AsciinemaApi{
url: url,
token: token,
2014-11-02 19:04:19 +01:00
http: &HttpClient{},
2014-08-03 20:48:48 +02:00
}
}
type AsciinemaApi struct {
url string
token string
2014-11-02 19:04:19 +01:00
http HTTP
2014-08-03 20:48:48 +02:00
}
2014-11-02 19:04:19 +01:00
func (a *AsciinemaApi) CreateAsciicast(frames []Frame, duration time.Duration, cols, rows int, command, title string) (string, error) {
files := map[string]io.Reader{
"asciicast[stdout]:stdout": gzippedDataReader(frames),
"asciicast[stdout_timing]:stdout.time": gzippedTimingReader(frames),
"asciicast[meta]:meta.json": metadataReader(duration, cols, rows, command, title),
}
// TODO: set proper user agent
response, err := a.http.PostForm(a.url+"/api/asciicasts", os.Getenv("USER"), a.token, files)
if err != nil {
return "", err
}
defer response.Body.Close()
body := &bytes.Buffer{}
_, err = body.ReadFrom(response.Body)
if err != nil {
return "", err
}
// TODO: handle non-200 statuses
return body.String(), nil
2014-08-03 20:48:48 +02:00
}
2014-11-02 19:04:19 +01:00
func gzippedDataReader(frames []Frame) io.Reader {
data := &bytes.Buffer{}
w := gzip.NewWriter(data)
for _, frame := range frames {
w.Write(frame.Data)
}
w.Close()
return data
}
func gzippedTimingReader(frames []Frame) io.Reader {
timing := &bytes.Buffer{}
w := gzip.NewWriter(timing)
for _, frame := range frames {
w.Write([]byte(fmt.Sprintf("%f %d\n", frame.Delay, len(frame.Data))))
}
w.Close()
return timing
2014-08-03 19:50:39 +02:00
}
2014-11-02 19:04:19 +01:00
func metadataReader(duration time.Duration, cols, rows int, command, title string) io.Reader {
metadata := map[string]interface{}{
"duration": duration.Seconds(),
"title": title,
"command": command,
"shell": os.Getenv("SHELL"),
"term": map[string]interface{}{
"type": os.Getenv("TERM"),
"columns": cols,
"lines": rows,
},
2014-08-03 19:50:39 +02:00
}
2014-11-02 19:04:19 +01:00
buf := &bytes.Buffer{}
encoder := json.NewEncoder(buf)
encoder.Encode(metadata)
return buf
2014-08-03 19:50:39 +02:00
}