All checks were successful
Reply to a message containing a link with !gallerydl (or send it with a link inline) to download the media via the gallery-dl CLI and have the files posted back as a reply. Restricted to an allowed_users allowlist (comma-separated, per-channel/global config); no one is allowed by default. - Add media support to the platform layer: model.Message.Files, ActionSendMedia, and Platform.SendMedia. Telegram uploads via multipart (sendPhoto/sendVideo/sendDocument, 50MB cap); Slack returns unsupported for now. - Add internal/shell (os/exec wrapper) and internal/urlutil (URL extraction) helpers with tests. - Dispatch ActionSendMedia in app and clean up the temp download dir. - Admin config UI for allowed_users / gallery_dl_path; docs entry. - Containerfile: base on alpine and install gallery-dl + ffmpeg (was scratch); release workflow sets up QEMU + Buildx for cross-arch image builds.
53 lines
1.3 KiB
Go
53 lines
1.3 KiB
Go
// Package urlutil provides helpers for pulling URLs out of arbitrary text.
|
|
package urlutil
|
|
|
|
import (
|
|
"net/url"
|
|
"regexp"
|
|
)
|
|
|
|
// urlPattern matches http(s) URLs embedded in free-form text.
|
|
var urlPattern = regexp.MustCompile(`https?://[^\s]+`)
|
|
|
|
// ExtractURLs returns the http(s) URLs found in text, in order of appearance
|
|
// and without duplicates. Trailing punctuation that is unlikely to be part of
|
|
// a URL (e.g. a sentence-ending period or a wrapping parenthesis) is trimmed,
|
|
// and each candidate is validated with url.Parse.
|
|
func ExtractURLs(text string) []string {
|
|
matches := urlPattern.FindAllString(text, -1)
|
|
|
|
seen := make(map[string]struct{}, len(matches))
|
|
urls := make([]string, 0, len(matches))
|
|
|
|
for _, match := range matches {
|
|
candidate := trimURL(match)
|
|
|
|
parsed, err := url.Parse(candidate)
|
|
if err != nil || parsed.Host == "" {
|
|
continue
|
|
}
|
|
|
|
if _, ok := seen[candidate]; ok {
|
|
continue
|
|
}
|
|
seen[candidate] = struct{}{}
|
|
urls = append(urls, candidate)
|
|
}
|
|
|
|
return urls
|
|
}
|
|
|
|
// trimURL strips common trailing characters that are almost never part of the
|
|
// URL itself when it appears inside a sentence.
|
|
func trimURL(s string) string {
|
|
for len(s) > 0 {
|
|
last := s[len(s)-1]
|
|
switch last {
|
|
case '.', ',', ';', ':', '!', '?', ')', ']', '}', '"', '\'', '>':
|
|
s = s[:len(s)-1]
|
|
default:
|
|
return s
|
|
}
|
|
}
|
|
return s
|
|
}
|