mirror of
https://github.com/m1k1o/neko.git
synced 2025-04-29 18:36:22 +02:00
legacy: implement screenshot function.
This commit is contained in:
parent
88b9663c7c
commit
0f4ee18f18
3 changed files with 65 additions and 41 deletions
|
@ -4,7 +4,9 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"m1k1o/neko/internal/api"
|
"m1k1o/neko/internal/api"
|
||||||
|
@ -264,38 +266,42 @@ func (h *LegacyHandler) Route(r types.Router) {
|
||||||
return json.NewEncoder(w).Encode(stats)
|
return json.NewEncoder(w).Encode(stats)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
s := newSession(h.logger, h.serverAddr)
|
||||||
|
|
||||||
|
// create a new session
|
||||||
|
username := r.URL.Query().Get("usr")
|
||||||
|
password := r.URL.Query().Get("pwd")
|
||||||
|
err := s.create(username, password)
|
||||||
|
if err != nil {
|
||||||
|
return utils.HttpForbidden(err.Error())
|
||||||
|
}
|
||||||
|
defer s.destroy()
|
||||||
|
|
||||||
|
if !s.isAdmin {
|
||||||
|
return utils.HttpUnauthorized().Msg("bad authorization")
|
||||||
|
}
|
||||||
|
|
||||||
|
quality, err := strconv.Atoi(r.URL.Query().Get("quality"))
|
||||||
|
if err != nil {
|
||||||
|
quality = 90
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
|
w.Header().Set("Content-Type", "image/jpeg")
|
||||||
|
|
||||||
|
// get the screenshot
|
||||||
|
body, err := s.req(http.MethodGet, "/api/room/screen/shot.jpg?quality="+strconv.Itoa(quality), nil)
|
||||||
|
if err != nil {
|
||||||
|
return utils.HttpInternalServerError().WithInternalErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the body to the response writer
|
||||||
|
_, err = io.Copy(w, body)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error {
|
|
||||||
password := r.URL.Query().Get("pwd")
|
|
||||||
isAdmin, err := webSocketHandler.IsAdmin(password)
|
|
||||||
if err != nil {
|
|
||||||
return utils.HttpForbidden(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !isAdmin {
|
|
||||||
return utils.HttpUnauthorized().Msg("bad authorization")
|
|
||||||
}
|
|
||||||
|
|
||||||
if webSocketHandler.IsLocked("login") {
|
|
||||||
return utils.HttpError(http.StatusLocked).Msg("room is locked")
|
|
||||||
}
|
|
||||||
|
|
||||||
quality, err := strconv.Atoi(r.URL.Query().Get("quality"))
|
|
||||||
if err != nil {
|
|
||||||
quality = 90
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
|
||||||
w.Header().Set("Content-Type", "image/jpeg")
|
|
||||||
|
|
||||||
img := desktop.GetScreenshotImage()
|
|
||||||
if err := jpeg.Encode(w, img, &jpeg.Options{Quality: quality}); err != nil {
|
|
||||||
return utils.HttpInternalServerError().WithInternalErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// allow downloading and uploading files
|
// allow downloading and uploading files
|
||||||
if webSocketHandler.FileTransferEnabled() {
|
if webSocketHandler.FileTransferEnabled() {
|
||||||
r.Get("/file", func(w http.ResponseWriter, r *http.Request) error {
|
r.Get("/file", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
|
|
@ -57,15 +57,15 @@ func newSession(logger zerolog.Logger, serverAddr string) *session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) apiReq(method, path string, request, response any) error {
|
func (s *session) req(method, path string, request any) (io.ReadCloser, error) {
|
||||||
body, err := json.Marshal(request)
|
body, err := json.Marshal(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(method, "http://"+s.serverAddr+path, bytes.NewReader(body))
|
req, err := http.NewRequest(method, "http://"+s.serverAddr+path, bytes.NewReader(body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
@ -76,33 +76,44 @@ func (s *session) apiReq(method, path string, request, response any) error {
|
||||||
|
|
||||||
res, err := s.client.Do(req)
|
res, err := s.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
|
||||||
|
|
||||||
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
body, _ := io.ReadAll(res.Body)
|
body, _ := io.ReadAll(res.Body)
|
||||||
// try to unmarsal as json error message
|
// try to unmarsal as json error message
|
||||||
var apiErr struct {
|
var apiErr struct {
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(body, &apiErr); err == nil {
|
if err := json.Unmarshal(body, &apiErr); err == nil {
|
||||||
return fmt.Errorf("%w: %s", ErrBackendRespone, apiErr.Message)
|
return nil, fmt.Errorf("%w: %s", ErrBackendRespone, apiErr.Message)
|
||||||
}
|
}
|
||||||
// return raw body if failed to unmarshal
|
// return raw body if failed to unmarshal
|
||||||
return fmt.Errorf("unexpected status code: %d, body: %s", res.StatusCode, strings.TrimSpace(string(body)))
|
return nil, fmt.Errorf("unexpected status code: %d, body: %s", res.StatusCode, strings.TrimSpace(string(body)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Body == nil {
|
return res.Body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *session) apiReq(method, path string, request, response any) error {
|
||||||
|
body, err := s.req(method, path, request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer body.Close()
|
||||||
|
|
||||||
|
if body == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if response == nil {
|
if response == nil {
|
||||||
io.Copy(io.Discard, res.Body)
|
io.Copy(io.Discard, body)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.NewDecoder(res.Body).Decode(response)
|
return json.NewDecoder(body).Decode(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send message to client (in old format)
|
// send message to client (in old format)
|
||||||
|
|
|
@ -703,6 +703,13 @@ paths:
|
||||||
- room
|
- room
|
||||||
summary: get screenshot image
|
summary: get screenshot image
|
||||||
operationId: screenShotImage
|
operationId: screenShotImage
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: quality
|
||||||
|
description: image quality (0-100)
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
|
Loading…
Add table
Reference in a new issue