Files
gaslight/internal/rewrite/html.go
2026-05-19 14:12:22 +03:00

134 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package rewrite
import (
"bytes"
"compress/flate"
"compress/gzip"
"fmt"
"io"
"log"
"net/http"
"regexp"
"strings"
"git.gulenok.ru/greenhaze/gaslight/internal/cheating"
"git.gulenok.ru/greenhaze/gaslight/internal/latex"
"git.gulenok.ru/greenhaze/gaslight/internal/openrouter"
)
var questionTestDivRe = regexp.MustCompile(`(?is)<div[^>]*\bid\s*=\s*["'][^"']*\bQuestionTest\b[^"']*["'][^>]*>`)
type HTMLHook func(req *http.Request, html []byte) ([]byte, error)
type Processor struct {
hook HTMLHook
}
func NewProcessor(hook HTMLHook) *Processor {
return &Processor{hook: hook}
}
func tryExtractLinks(text string) []string {
aiResponce, err := openrouter.AskOpenRouter(fmt.Sprintf("Ты - умный парсер для веб страниц. Данная страница представляет из себя тестовое задание и тебе нужно проанализировать страницу, найти блок в котором находится задание, и если внутри этого блока есть изображения - достать их и вернуть в виде JSON массива со строками на эти изображения. ВОЗВРАЩАЙ ТОЛЬКО И ТОЛЬКО JSON обьект, БЕЗ КАКИХ ЛИБО ДОПОЛНИТЕЛЬНЫХ СЛОВ, ФРАЗ, СИМВОЛОВ etc. В ФОРМАТЕ {\"images\":[\"test", "test\"]}", string(text)))
if err != nil {
log.Printf("openrouter failed %s", err)
return []string{}
}
log.Println(aiResponce)
return []string{}
}
func DefaultQuestionTestHook(_ *http.Request, html []byte) ([]byte, error) {
switch cheating.DetermineQuestionType(string(html)) {
case cheating.FullTextQuestion:
{
//log.Println(tryExtractLinks(string(html)))
aiResponce, err := openrouter.AskOpenRouter(fmt.Sprintf("прочитай задание и выпиши достаточно подробный список формул/гайд по решению которые могут помочь при решении задач ИЛИ ЕСЛИ МОЖЕШЬ СРАЗУ ДАТЬ ОТВЕТ - ответы списком: %s. пиши без latex обычным читаемым текстом и максимально кратко. учти что это работа за 10 класс российской школы", string(html)))
if err != nil {
log.Printf("openrouter failed %s", err)
return html, nil
}
return []byte(strings.ReplaceAll(string(html), "generated", fmt.Sprintf("<span title=\"%s\">generated</span>", latex.ConvertLaTeXToASCII(aiResponce)))), nil
}
case cheating.QuestionWithPicture:
{
}
}
return []byte(strings.ReplaceAll(string(html), "generated", "pwned")), nil
}
func IsHTMLResponse(contentType string) bool {
contentType = strings.ToLower(contentType)
return strings.Contains(contentType, "text/html") || strings.Contains(contentType, "application/xhtml+xml")
}
func (p *Processor) RewriteIfNeeded(req *http.Request, contentEncoding string, body []byte) ([]byte, error) {
decoded, err := decodeBody(contentEncoding, body)
if err != nil {
return nil, err
}
if !questionTestDivRe.Match(decoded) {
return body, nil
}
modifiedDecoded, err := p.hook(req, decoded)
if err != nil {
return nil, err
}
return encodeBody(contentEncoding, modifiedDecoded)
}
func decodeBody(encoding string, body []byte) ([]byte, error) {
switch strings.ToLower(strings.TrimSpace(encoding)) {
case "", "identity":
return body, nil
case "gzip":
r, err := gzip.NewReader(bytes.NewReader(body))
if err != nil {
return nil, err
}
defer r.Close()
return io.ReadAll(r)
case "deflate":
r := flate.NewReader(bytes.NewReader(body))
defer r.Close()
return io.ReadAll(r)
default:
return nil, fmt.Errorf("unsupported content-encoding: %s", encoding)
}
}
func encodeBody(encoding string, decoded []byte) ([]byte, error) {
switch strings.ToLower(strings.TrimSpace(encoding)) {
case "", "identity":
return decoded, nil
case "gzip":
var buf bytes.Buffer
w := gzip.NewWriter(&buf)
if _, err := w.Write(decoded); err != nil {
_ = w.Close()
return nil, err
}
if err := w.Close(); err != nil {
return nil, err
}
return buf.Bytes(), nil
case "deflate":
var buf bytes.Buffer
w, err := flate.NewWriter(&buf, flate.DefaultCompression)
if err != nil {
return nil, err
}
if _, err := w.Write(decoded); err != nil {
_ = w.Close()
return nil, err
}
if err := w.Close(); err != nil {
return nil, err
}
return buf.Bytes(), nil
default:
return nil, fmt.Errorf("unsupported content-encoding: %s", encoding)
}
}