Skip to content

Commit 4e8dbec

Browse files
Gautam Deygdey
authored andcommitted
Added a self-contained viewer
Added a self contained viewer that one can startup from the command line. This viewer includes everything in the binary. Added scripts to build the viewer, and the travis ci scripts as well.
1 parent c1cb520 commit 4e8dbec

File tree

5 files changed

+794
-0
lines changed

5 files changed

+794
-0
lines changed

.travis.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
language: node_js
2+
3+
apt:
4+
update: true
5+
6+
git:
7+
depth: 2
8+
9+
node_js:
10+
- node
11+
12+
go:
13+
- 1.x
14+
15+
script:
16+
- echo "skipping tests."
17+
- bash -x ci/build_viewer.sh
18+
19+
deploy:
20+
provider: releases
21+
api_key:
22+
secure: Bu21GK4lUA/h/d710zTvP9aS2oxzxiwgCETv7fDqJ86xeVla9PGUu1v0G60l5zmTBO9ft1fmdk5S3TinZWWT4Q+uRslzB6VEM/04+/ZnEdmDlfO0r0+K9MzVy6l5C1NVyA1f+Zp30fDKgKy/0qSo3bHs+eztvG9aFD2rkyj3K8cS+vTzxVzShdg5zFL+56rV+IwwV1D2bKzkY+6cbrd6657Uk2TpV6OILo3mjMRWJMR7NcHi8nGh3nAT1qMkP5mBnZfkKR5ni76qGBGeW2PexsPnlwNqgYCLugTqzO7HsIxiMSsaqJWvuY83jXzY9BqdyksRITD9lwCBUVUSVwXW5kelWvK3rb5QKTnqxcSh8gsle1QowZxxHbjfc3bn7GQhuYE5Ic+AYw3GMxBKxe7Ma38y354xsECjmRuXTgjoBw7iypJ/jPPdfLTxMYKtGNfpdFTySbOlyOyB8rvX1P7J86V+fTxklLrKeF2nwI27YkupBDu3WzQEwo+guWqNp+xIQuwXqiicTgabLnIbZIddk3L5Nmc38Y9EaxM6rW5Zfps821a0OEq/34HHirCSYrkFTy8Oqdqb9NDSV5UwcwdBCyavRnUAIwTWjzLcmAqaXTndGbenv+2Hl2J/MrgnaJT4lEedppZbdt9nVA5vfJEEjM18E8K0iy3wFb1d9sOR12g=
23+
file_glob: true
24+
file: releases/*
25+
skip_cleanup: true
26+
on:
27+
tags: true

ci/build_viewer.sh

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/bin/bash -x
2+
3+
set -e
4+
5+
################################################################################
6+
# This script will build the necessary binaries for the fresco viewer. #
7+
################################################################################
8+
9+
OLDIR=$(pwd)
10+
VERSION_TAG=$TRAVIS_TAG
11+
if [ -z ${PROJECT_DIR+x} ]; then
12+
PROJECT_DIR=`dirname $0`/..
13+
fi
14+
15+
cd $PROJECT_DIR
16+
17+
# Let's make it absolute
18+
PROJECT_DIR=$(pwd)
19+
20+
21+
if [ -z "$VERSION_TAG" ]; then
22+
VERSION_TAG=$(git rev-parse --short HEAD)
23+
fi
24+
25+
LDFLAGS="-w -X main.Version=${VERSION_TAG}"
26+
export CGO_ENABLED=0
27+
28+
if [ -z "$TRAVIS_BUILD_DIR" ]; then
29+
TRAVIS_BUILD_DIR=$PROJECT_DIR
30+
fi
31+
32+
mkdir -p "${TRAVIS_BUILD_DIR}/releases"
33+
34+
go get github.com/elazarl/go-bindata-assetfs
35+
go get github.com/jteeuwen/go-bindata/go-bindata
36+
37+
38+
ls -l "$GOPATH/bin"
39+
40+
# Disable warnings as fatal for npm
41+
unset CI
42+
echo "generating assets"
43+
go generate ./...
44+
45+
echo "build zip of assets"
46+
47+
cd $PROJECT_DIR/build
48+
zip -9 -r -D ${TRAVIS_BUILD_DIR}/releases/dist.zip .
49+
cd $PROJECT_DIR
50+
51+
52+
echo "building bin into ${TRAVIS_BUILD_DIR}"
53+
54+
for GOARCH in amd64
55+
do
56+
for GOOS in darwin linux windows
57+
do
58+
FILENAME="${TRAVIS_BUILD_DIR}/releases/viewer_${GOOS}_${GOARCH}"
59+
60+
GOOS=${GOOS} GOARCH=${GOARCH} go build -ldflags "${LDFLAGS}" -o ${FILENAME} cmd/viewer/*.go
61+
62+
chmod a+x ${FILENAME}
63+
dir=$(dirname $FILENAME)
64+
fn=$(basename $FILENAME)
65+
cdir=$(pwd)
66+
cd $dir
67+
68+
zip -9 -D ${fn}.zip ${fn}
69+
rm ${fn}
70+
cd ${cdir}
71+
done
72+
done
73+
cd $OLDDIR
74+

cmd/viewer/assetfs.go

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// this package is a copy of "github.com/elazarl/go-bindata-assetfs"
2+
// with minor modifications making `assetFS` `public via `AssetFileServer`
3+
4+
package main
5+
6+
import (
7+
"bytes"
8+
"errors"
9+
"io"
10+
"io/ioutil"
11+
"log"
12+
"net/http"
13+
"os"
14+
"path"
15+
"path/filepath"
16+
"strings"
17+
"time"
18+
19+
assetfs "github.com/elazarl/go-bindata-assetfs"
20+
)
21+
22+
var (
23+
defaultFileTimestamp = time.Now()
24+
)
25+
26+
// FakeFile implements os.FileInfo interface for a given path and size
27+
type FakeFile struct {
28+
// Path is the path of this file
29+
Path string
30+
// Dir marks of the path is a directory
31+
Dir bool
32+
// Len is the length of the fake file, zero if it is a directory
33+
Len int64
34+
// Timestamp is the ModTime of this file
35+
Timestamp time.Time
36+
}
37+
38+
func (f *FakeFile) Name() string {
39+
_, name := filepath.Split(f.Path)
40+
return name
41+
}
42+
43+
func (f *FakeFile) Mode() os.FileMode {
44+
mode := os.FileMode(0644)
45+
if f.Dir {
46+
return mode | os.ModeDir
47+
}
48+
return mode
49+
}
50+
51+
func (f *FakeFile) ModTime() time.Time {
52+
return f.Timestamp
53+
}
54+
55+
func (f *FakeFile) Size() int64 {
56+
return f.Len
57+
}
58+
59+
func (f *FakeFile) IsDir() bool {
60+
return f.Mode().IsDir()
61+
}
62+
63+
func (f *FakeFile) Sys() interface{} {
64+
return nil
65+
}
66+
67+
// AssetFile implements http.File interface for a no-directory file with content
68+
type AssetFile struct {
69+
*bytes.Reader
70+
io.Closer
71+
FakeFile
72+
}
73+
74+
func NewAssetFile(name string, content []byte, timestamp time.Time) *AssetFile {
75+
if timestamp.IsZero() {
76+
timestamp = defaultFileTimestamp
77+
}
78+
return &AssetFile{
79+
bytes.NewReader(content),
80+
ioutil.NopCloser(nil),
81+
FakeFile{name, false, int64(len(content)), timestamp}}
82+
}
83+
84+
func (f *AssetFile) Readdir(count int) ([]os.FileInfo, error) {
85+
return nil, errors.New("not a directory")
86+
}
87+
88+
func (f *AssetFile) Size() int64 {
89+
return f.FakeFile.Size()
90+
}
91+
92+
func (f *AssetFile) Stat() (os.FileInfo, error) {
93+
return f, nil
94+
}
95+
96+
// AssetDirectory implements http.File interface for a directory
97+
type AssetDirectory struct {
98+
AssetFile
99+
ChildrenRead int
100+
Children []os.FileInfo
101+
}
102+
103+
func NewAssetDirectory(name string, children []string, fs *AssetFS) *AssetDirectory {
104+
fileinfos := make([]os.FileInfo, 0, len(children))
105+
for _, child := range children {
106+
_, err := fs.AssetDir(filepath.Join(name, child))
107+
fileinfos = append(fileinfos, &FakeFile{child, err == nil, 0, time.Time{}})
108+
}
109+
return &AssetDirectory{
110+
AssetFile{
111+
bytes.NewReader(nil),
112+
ioutil.NopCloser(nil),
113+
FakeFile{name, true, 0, time.Time{}},
114+
},
115+
0,
116+
fileinfos}
117+
}
118+
119+
func (f *AssetDirectory) Readdir(count int) ([]os.FileInfo, error) {
120+
if count <= 0 {
121+
return f.Children, nil
122+
}
123+
if f.ChildrenRead+count > len(f.Children) {
124+
count = len(f.Children) - f.ChildrenRead
125+
}
126+
rv := f.Children[f.ChildrenRead : f.ChildrenRead+count]
127+
f.ChildrenRead += count
128+
return rv, nil
129+
}
130+
131+
func (f *AssetDirectory) Stat() (os.FileInfo, error) {
132+
return f, nil
133+
}
134+
135+
// AssetFS implements http.FileSystem, allowing
136+
// embedded files to be served from net/http package.
137+
type AssetFS struct {
138+
// Asset should return content of file in path if exists
139+
Asset func(path string) ([]byte, error)
140+
// AssetDir should return list of files in the path
141+
AssetDir func(path string) ([]string, error)
142+
// AssetInfo should return the info of file in path if exists
143+
AssetInfo func(path string) (os.FileInfo, error)
144+
// Prefix would be prepended to http requests
145+
Prefix string
146+
}
147+
148+
func (fs *AssetFS) Open(name string) (http.File, error) {
149+
log.Printf("Looking for (pre): %v",name)
150+
name = path.Join(fs.Prefix, name)
151+
log.Printf("Looking for (post): %v",name)
152+
if len(name) > 0 && name[0] == '/' {
153+
name = name[1:]
154+
}
155+
if b, err := fs.Asset(name); err == nil {
156+
timestamp := defaultFileTimestamp
157+
if fs.AssetInfo != nil {
158+
if info, err := fs.AssetInfo(name); err == nil {
159+
timestamp = info.ModTime()
160+
}
161+
}
162+
return NewAssetFile(name, b, timestamp), nil
163+
}
164+
if children, err := fs.AssetDir(name); err == nil {
165+
return NewAssetDirectory(name, children, fs), nil
166+
} else {
167+
// If the error is not found, return an error that will
168+
// result in a 404 error. Otherwise the server returns
169+
// a 500 error for files not found.
170+
if strings.Contains(err.Error(), "not found") {
171+
return nil, os.ErrNotExist
172+
}
173+
return nil, err
174+
}
175+
}
176+
177+
func AssetFileSystem() *assetfs.AssetFS {
178+
assetInfo := func(path string) (os.FileInfo, error) {
179+
return os.Stat(path)
180+
}
181+
for k := range _bintree.Children {
182+
return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: assetInfo, Prefix: k}
183+
}
184+
panic("unreachable")
185+
}

0 commit comments

Comments
 (0)