go-tg-screenshot-bot
97 строк · 2.5 Кб
1//go:build !s390x && !ppc64le && !darwin && !windows && !freebsd && (linux || openbsd || netbsd)
2
3package screenshot4
5import (6"fmt"7"github.com/godbus/dbus/v5"8"image"9"image/draw"10"image/png"11"net/url"12"os"13"sync/atomic"14)
15
16var gTokenCounter uint64 = 017
18func captureDbus(x, y, width, height int) (img *image.RGBA, e error) {19c, err := dbus.ConnectSessionBus()20if err != nil {21return nil, fmt.Errorf("dbus.SessionBus() failed: %v", err)22}23defer func(c *dbus.Conn) {24err := c.Close()25if err != nil {26e = err27}28}(c)29token := atomic.AddUint64(&gTokenCounter, 1)30options := map[string]dbus.Variant{31"modal": dbus.MakeVariant(false),32"interactive": dbus.MakeVariant(false),33"handle_token": dbus.MakeVariant(token),34}35obj := c.Object("org.freedesktop.portal.Desktop", dbus.ObjectPath("/org/freedesktop/portal/desktop"))36call := obj.Call("org.freedesktop.portal.Screenshot.Screenshot", 0, "", options)37var path dbus.ObjectPath38err = call.Store(&path)39if err != nil {40return nil, fmt.Errorf("dbus.Store() failed: %v", err)41}42ch := make(chan *dbus.Message)43c.Eavesdrop(ch)44for msg := range ch {45o, ok := msg.Headers[dbus.FieldPath]46if !ok {47continue48}49s, ok := o.Value().(dbus.ObjectPath)50if !ok {51return nil, fmt.Errorf("dbus.FieldPath value does't have ObjectPath type")52}53if s != path {54continue55}56for _, body := range msg.Body {57v, ok := body.(map[string]dbus.Variant)58if !ok {59continue60}61uri, ok := v["uri"]62if !ok {63continue64}65path, ok := uri.Value().(string)66if !ok {67return nil, fmt.Errorf("uri is not a string")68}69fpath, err := url.Parse(path)70if err != nil {71return nil, fmt.Errorf("url.Parse(%v) failed: %v", path, err)72}73if fpath.Scheme != "file" {74return nil, fmt.Errorf("uri is not a file path")75}76file, err := os.Open(fpath.Path)77if err != nil {78return nil, fmt.Errorf("os.Open(%s) failed: %v", path, err)79}80defer func(file *os.File) {81_ = file.Close()82_ = os.Remove(fpath.Path)83}(file)84img, err := png.Decode(file)85if err != nil {86return nil, fmt.Errorf("png.Decode(%s) failed: %v", path, err)87}88canvas, err := createImage(image.Rect(0, 0, width, height))89if err != nil {90return nil, fmt.Errorf("createImage(%v) failed: %v", path, err)91}92draw.Draw(canvas, image.Rect(0, 0, width, height), img, image.Point{x, y}, draw.Src)93return canvas, e94}95}96return nil, fmt.Errorf("dbus.Message doesn't contain uri")97}
98