go-tg-screenshot-bot

Форк
0
97 строк · 2.5 Кб
1
//go:build !s390x && !ppc64le && !darwin && !windows && !freebsd && (linux || openbsd || netbsd)
2

3
package screenshot
4

5
import (
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

16
var gTokenCounter uint64 = 0
17

18
func captureDbus(x, y, width, height int) (img *image.RGBA, e error) {
19
	c, err := dbus.ConnectSessionBus()
20
	if err != nil {
21
		return nil, fmt.Errorf("dbus.SessionBus() failed: %v", err)
22
	}
23
	defer func(c *dbus.Conn) {
24
		err := c.Close()
25
		if err != nil {
26
			e = err
27
		}
28
	}(c)
29
	token := atomic.AddUint64(&gTokenCounter, 1)
30
	options := map[string]dbus.Variant{
31
		"modal":        dbus.MakeVariant(false),
32
		"interactive":  dbus.MakeVariant(false),
33
		"handle_token": dbus.MakeVariant(token),
34
	}
35
	obj := c.Object("org.freedesktop.portal.Desktop", dbus.ObjectPath("/org/freedesktop/portal/desktop"))
36
	call := obj.Call("org.freedesktop.portal.Screenshot.Screenshot", 0, "", options)
37
	var path dbus.ObjectPath
38
	err = call.Store(&path)
39
	if err != nil {
40
		return nil, fmt.Errorf("dbus.Store() failed: %v", err)
41
	}
42
	ch := make(chan *dbus.Message)
43
	c.Eavesdrop(ch)
44
	for msg := range ch {
45
		o, ok := msg.Headers[dbus.FieldPath]
46
		if !ok {
47
			continue
48
		}
49
		s, ok := o.Value().(dbus.ObjectPath)
50
		if !ok {
51
			return nil, fmt.Errorf("dbus.FieldPath value does't have ObjectPath type")
52
		}
53
		if s != path {
54
			continue
55
		}
56
		for _, body := range msg.Body {
57
			v, ok := body.(map[string]dbus.Variant)
58
			if !ok {
59
				continue
60
			}
61
			uri, ok := v["uri"]
62
			if !ok {
63
				continue
64
			}
65
			path, ok := uri.Value().(string)
66
			if !ok {
67
				return nil, fmt.Errorf("uri is not a string")
68
			}
69
			fpath, err := url.Parse(path)
70
			if err != nil {
71
				return nil, fmt.Errorf("url.Parse(%v) failed: %v", path, err)
72
			}
73
			if fpath.Scheme != "file" {
74
				return nil, fmt.Errorf("uri is not a file path")
75
			}
76
			file, err := os.Open(fpath.Path)
77
			if err != nil {
78
				return nil, fmt.Errorf("os.Open(%s) failed: %v", path, err)
79
			}
80
			defer func(file *os.File) {
81
				_ = file.Close()
82
				_ = os.Remove(fpath.Path)
83
			}(file)
84
			img, err := png.Decode(file)
85
			if err != nil {
86
				return nil, fmt.Errorf("png.Decode(%s) failed: %v", path, err)
87
			}
88
			canvas, err := createImage(image.Rect(0, 0, width, height))
89
			if err != nil {
90
				return nil, fmt.Errorf("createImage(%v) failed: %v", path, err)
91
			}
92
			draw.Draw(canvas, image.Rect(0, 0, width, height), img, image.Point{x, y}, draw.Src)
93
			return canvas, e
94
		}
95
	}
96
	return nil, fmt.Errorf("dbus.Message doesn't contain uri")
97
}
98

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.