This commit is contained in:
2022-05-17 01:56:44 +03:00
commit 3a9b8c8468
117 changed files with 7175 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
FROM golang:1.17 as go
COPY xseld /xseld
COPY fileserver /fileserver
RUN \
apt-get update && \
apt-get install -y upx-ucl libx11-dev && \
cd /xseld && \
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" && \
upx /xseld/xseld && \
cd /fileserver && \
go test -race && \
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" && \
upx /fileserver/fileserver
FROM ubuntu:20.04
RUN \
apt update && \
apt remove -y libcurl4 && \
apt install -y apt-transport-https ca-certificates tzdata locales libcurl4 curl gnupg && \
DEBIAN_FRONTEND=noninteractive apt -y upgrade && \
echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections && \
echo 'UTC' | tee /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata && \
echo "gtk-cursor-blink=0" > /root/.gtkrc-2.0 && \
apt update && \
apt install -y ttf-mscorefonts-installer \
ttf-dejavu-core \
fontconfig \
fontconfig-config \
fonts-dejavu-core \
fonts-liberation \
fonts-ubuntu-font-family-console \
fonts-wqy-zenhei \
fonts-thai-tlwg-ttf \
fonts-ipafont-mincho \
fonts-sahadeva \
fonts-noto-unhinted \
fonts-noto-color-emoji \
libfontconfig1 \
libfontenc1 \
libfreetype6 \
libxfont2 \
libxft2 \
libnss3-tools \
xfonts-base \
xfonts-encodings \
xfonts-utils \
flashplugin-installer \
xvfb \
pulseaudio \
fluxbox \
x11vnc \
feh \
wmctrl \
libnss-wrapper \
xsel && \
mkdir -p /var/lib/locales/supported.d/ && grep UTF-8 /usr/share/i18n/SUPPORTED > /var/lib/locales/supported.d/all && \
locale-gen && update-locale && \
fc-cache -f -v && \
adduser --system --home /home/selenium --uid 4096 \
--ingroup root --disabled-password --shell /bin/bash selenium && \
mkdir -p /home/selenium/Downloads && \
mkdir -p /home/selenium/.fluxbox && \
chgrp -R 0 /home/selenium && \
chmod -R g=u /home/selenium && \
ln -sf /bin/true /usr/bin/xdg-open && \
apt-get clean && \
rm -Rf /tmp/* && rm -Rf /var/lib/apt/lists/*
COPY fluxbox /usr/share/fluxbox/styles/
COPY --chown=selenium:root fluxbox /home/selenium/.fluxbox/
COPY aerokube.png /usr/share/images/fluxbox/
COPY --from=go /fileserver/fileserver /usr/bin/
COPY --from=go /xseld/xseld /usr/bin/
Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

+5
View File
@@ -0,0 +1,5 @@
module fileserver
go 1.17
require github.com/aandryashin/matchers v0.0.0-20161126170413-435295ea180e
+2
View File
@@ -0,0 +1,2 @@
github.com/aandryashin/matchers v0.0.0-20161126170413-435295ea180e h1:ogUKYFNcdYUIBSLibE4+EjbTJazoHr5JsWWx21Lpn8c=
github.com/aandryashin/matchers v0.0.0-20161126170413-435295ea180e/go.mod h1:cbmYNkm9xeQlNoWEPtOUcvNok2gSD7ErMnYkRW+eHi8=
+84
View File
@@ -0,0 +1,84 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
)
func main() {
dir, err := downloadsDir()
if err != nil {
log.Fatal(err)
}
log.Fatal(http.ListenAndServe(":8080", mux(dir)))
}
func downloadsDir() (string, error) {
homeDir := os.Getenv("HOME")
if homeDir == "" {
homeDir = "/home/selenium"
}
dir := filepath.Join(homeDir, "Downloads")
err := os.MkdirAll(dir, 0755)
if err != nil {
return "", fmt.Errorf("failed to create downloads dir: %v", err)
}
return dir, nil
}
const jsonParam = "json"
func mux(dir string) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodDelete {
deleteFileIfExists(w, r, dir)
return
}
if _, ok := r.URL.Query()[jsonParam]; ok {
listFilesAsJson(w, dir)
return
}
http.FileServer(http.Dir(dir)).ServeHTTP(w, r)
})
return mux
}
func listFilesAsJson(w http.ResponseWriter, dir string) {
files, err := ioutil.ReadDir(dir)
sort.Slice(files, func(i, j int) bool {
return files[i].ModTime().After(files[j].ModTime())
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
ret := []string{}
for _, f := range files {
ret = append(ret, f.Name())
}
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(ret)
}
func deleteFileIfExists(w http.ResponseWriter, r *http.Request, dir string) {
fileName := strings.TrimPrefix(r.URL.Path, "/")
filePath := filepath.Join(dir, fileName)
_, err := os.Stat(filePath)
if err != nil {
http.Error(w, fmt.Sprintf("Unknown file %s", fileName), http.StatusNotFound)
return
}
err = os.Remove(filePath)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to delete file %s: %v", fileName, err), http.StatusInternalServerError)
return
}
}
+58
View File
@@ -0,0 +1,58 @@
package main
import (
. "github.com/aandryashin/matchers"
. "github.com/aandryashin/matchers/httpresp"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
)
var (
dir string
srv *httptest.Server
)
func init() {
dir, _ = ioutil.TempDir("", "fileserver")
srv = httptest.NewServer(mux(dir))
}
func withUrl(path string) string {
return srv.URL + path
}
func TestDownloadAndRemoveFile(t *testing.T) {
tempFile, _ := ioutil.TempFile(dir, "fileserver")
ioutil.WriteFile(tempFile.Name(), []byte("test-data"), 0644)
tempFileName := filepath.Base(tempFile.Name())
resp, err := http.Get(withUrl("/" + tempFileName))
AssertThat(t, err, Is{nil})
AssertThat(t, resp, Code{200})
_, err = os.Stat(tempFile.Name())
AssertThat(t, err, Is{nil})
rsp, err := http.Get(withUrl("/?json"))
AssertThat(t, err, Is{nil})
AssertThat(t, rsp, Code{http.StatusOK})
var files []string
AssertThat(t, rsp, IsJson{&files})
AssertThat(t, files, EqualTo{[]string{tempFileName}})
req, _ := http.NewRequest(http.MethodDelete, withUrl("/" + tempFileName), nil)
resp, err = http.DefaultClient.Do(req)
AssertThat(t, err, Is{nil})
AssertThat(t, resp, Code{200})
_, err = os.Stat(tempFile.Name())
AssertThat(t, err, Not{nil})
}
func TestRemoveMissingFile(t *testing.T) {
req, _ := http.NewRequest(http.MethodDelete, withUrl("/missing-file"), nil)
resp, err := http.DefaultClient.Do(req)
AssertThat(t, err, Is{nil})
AssertThat(t, resp, Code{404})
}
+175
View File
@@ -0,0 +1,175 @@
###############################################################################
#
# name: aerokube (based on ubuntu_light)
# made: paultag
# date: 16-10-2010
# http://pault.ag/
#
############################################################## BACKGROUND ######
# background: flat
# background.color: #2c001e
# background.colorTo: #2c001e
background: fullscreen
background.pixmap: /usr/share/images/fluxbox/aerokube.png
############################################################## FONTS ##########
menu.frame.font: Ubuntu-10:bold
menu.title.font: Ubuntu-12:bold
toolbar.clock.font: Ubuntu-10:bold
toolbar.workspace.font: Ubuntu-12:bold
toolbar.iconbar.focused.font: Ubuntu-10:bold
toolbar.iconbar.unfocused.font: Ubuntu-10
window.font: Ubuntu-10
############################################################## MENU ###########
menu.bevelWidth: 1
#menu.itemHeight: 35
#menu.titleHeight: 21
menu.borderColor: #525252
menu.borderWidth: 1
menu.bullet: Triangle
menu.bullet.position: Right
menu.frame.underlineColor: #ffffff
menu.title: flat gradient rectangle
menu.title.justify: center
menu.title.color: #FFFFFF
menu.title.colorTo: #FFFFFF
menu.title.textColor: #333333
menu.frame: flat gradient crossdiagonal
menu.frame.justify: left
menu.frame.color: #FFFFFF
menu.frame.colorTo: #FFFFFF
menu.frame.textColor: #333333
menu.frame.disableColor: #aea79f
menu.hilite: flat gradient rectangle
menu.hilite.color: #aea79f
menu.hilite.colorTo: #aea79f
menu.hilite.textColor: #000000
############################################################## TOOLBAR ########
toolbar.bevelWidth: 0
toolbar.borderWidth: 1
toolbar.borderColor: #aea79f
toolbar.height: 20
toolbar.justify: center
toolbar: flat gradient rectangle
toolbar.pixmap:
toolbar.color: #aea79f
toolbar.colorTo: #aea79f
toolbar.clock: parentrelative
toolbar.clock.justify: center
toolbar.clock.color: #
toolbar.clock.colorTo: #
toolbar.clock.textColor: #333333
toolbar.workspace: parentrelative
toolbar.workspace.justify: Center
toolbar.workspace.color: #
toolbar.workspace.colorTo: #
toolbar.workspace.textColor: #333333
toolbar.button: parentrelative
toolbar.button.color: #333333
toolbar.button.colorTo: #333333
toolbar.button.picColor: #333333
toolbar.button.pressed: parentrelative
toolbar.button.pressed.color: #aea79f
toolbar.button.pressed.colorTo: #aea79f
toolbar.button.pressed.picColor: #000000
toolbar.iconbar.borderWidth: 1
toolbar.iconbar.borderColor: #333333
toolbar.iconbar.empty: parentrelative
toolbar.iconbar.empty.color: #
toolbar.iconbar.empty.colorTo: #
toolbar.iconbar.focused.borderWidth: 1
toolbar.iconbar.focused.borderColor: #333333
toolbar.iconbar.focused: flat gradient rectangle
toolbar.iconbar.focused.color: #FFFFFF
toolbar.iconbar.focused.colorTo: #FFFFFF
toolbar.iconbar.focused.textColor: #333333
toolbar.iconbar.focused.justify: center
toolbar.iconbar.unfocused.borderWidth: 1
toolbar.iconbar.unfocused.borderColor: #525252
toolbar.iconbar.unfocused: flat gradient rectangle
toolbar.iconbar.unfocused.color: #aea79f
toolbar.iconbar.unfocused.colorTo: #aea79f
toolbar.iconbar.unfocused.textColor: #444444
toolbar.iconbar.unfocused.justify: center
############################################################## WINDOW #########
window.roundCorners: TopRight TopLeft
window.bevelWidth: 4
window.shade: false
window.borderWidth: 1
window.borderColor: #333333
window.justify: Center
window.title.height: 21
window.title.focus: flat gradient rectangle
window.title.focus.color: #000000
window.title.focus.colorTo: #333333
window.title.unfocus: flat gradient rectangle
window.title.unfocus.color: #111111
window.title.unfocus.colorTo: #444444
window.label.focus: parentrelative
window.label.focus.color: #
window.label.focus.colorTo: #
window.label.focus.textColor: #FFFFFF
window.label.unfocus: parentrelative
window.label.unfocus.color: #
window.label.unfocus.colorTo: #
window.label.unfocus.textColor: #aea79f
window.button.focus: parentrelative
window.button.focus.color: #
window.button.focus.colorTo: #
window.button.focus.picColor: #FFFFFF
window.button.unfocus: parentrelative
window.button.unfocus.Color: #
window.button.unfocus.ColorTo: #
window.button.unfocus.picColor: #888888
window.button.pressed: parentrelative
window.button.pressed.color: #
window.button.pressed.colorTo: #
window.button.pressed.picColor: #000000
window.handle.focus: flat
window.handle.focus.color: #1f1f1f
window.handle.focus.colorTo: #1f1f1f
window.handle.unfocus: lat
window.handle.unfocus.color: #1f1f1f
window.handle.unfocus.colorTo: #1f1f1f
window.handleWidth: 2
window.grip.focus: flat
window.grip.focus.color: #525252
window.grip.focus.colorTo: #525252
window.grip.unfocus: flat
window.grip.unfocus.color: #1f1f1f
window.grip.unfocus.colorTo: #1f1f1f
###############################################################################
# EOF
+7
View File
@@ -0,0 +1,7 @@
session.menuFile: ~/.fluxbox/menu
session.keyFile: ~/.fluxbox/keys
session.styleFile: /usr/share/fluxbox/styles/aerokube
session.configVersion: 13
session.screen0.strftimeFormat: %d %b, %a %02k:%M:%S
session.screen0.toolbar.visible: false
session.screen0.toolbar.tools:
+3
View File
@@ -0,0 +1,3 @@
module xseld
go 1.17
+44
View File
@@ -0,0 +1,44 @@
package main
import (
"io"
"log"
"net/http"
"os/exec"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
cmd := exec.Command("xsel", "-b")
switch r.Method {
case http.MethodGet:
cmd.Args = append(cmd.Args, "-o")
stdout, err := cmd.StdoutPipe()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
go io.Copy(w, stdout)
case http.MethodPost:
cmd.Args = append(cmd.Args, "-i")
stdin, err := cmd.StdinPipe()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
go func() {
defer stdin.Close()
io.Copy(stdin, r.Body)
}()
default:
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
err := cmd.Run()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
log.Fatal(http.ListenAndServe(":9090", nil))
}