diff --git a/internal/upload/validate.go b/internal/upload/validate.go index 0bdc19f..d04b4c6 100644 --- a/internal/upload/validate.go +++ b/internal/upload/validate.go @@ -69,6 +69,10 @@ func ValidateYouTubeURL(raw string) error { switch strings.ToLower(parsed.Hostname()) { case "youtube.com", "www.youtube.com", "youtu.be", "m.youtube.com": return nil + case "x.com", "www.x.com", "mobile.x.com", "m.x.com": + return nil + case "twitter.com", "www.twitter.com", "mobile.twitter.com", "m.twitter.com": + return nil default: return ErrInvalidURL } diff --git a/internal/upload/validate_test.go b/internal/upload/validate_test.go index f269141..b84ed19 100644 --- a/internal/upload/validate_test.go +++ b/internal/upload/validate_test.go @@ -67,10 +67,16 @@ func TestValidateYouTubeURL(t *testing.T) { {name: "valid youtube watch", raw: "https://youtube.com/watch?v=X", wantErr: nil}, {name: "valid www", raw: "https://www.youtube.com/watch?v=X", wantErr: nil}, {name: "valid mobile", raw: "https://m.youtube.com/watch?v=X", wantErr: nil}, + {name: "valid x post", raw: "https://x.com/user/status/123", wantErr: nil}, + {name: "valid x video selector", raw: "https://www.x.com/user/status/123/video/2", wantErr: nil}, + {name: "valid mobile x", raw: "https://mobile.x.com/user/status/123", wantErr: nil}, + {name: "valid twitter post", raw: "https://twitter.com/user/status/123", wantErr: nil}, + {name: "valid mobile twitter", raw: "https://m.twitter.com/user/status/123", wantErr: nil}, {name: "empty", raw: "", wantErr: ErrInvalidURL}, {name: "not url", raw: "not-url", wantErr: ErrInvalidURL}, {name: "foreign host", raw: "https://example.com/watch?v=X", wantErr: ErrInvalidURL}, {name: "host confusion", raw: "https://youtu.be.evil.com/x", wantErr: ErrInvalidURL}, + {name: "x host confusion", raw: "https://x.com.evil.com/user/status/123", wantErr: ErrInvalidURL}, {name: "ftp scheme", raw: "ftp://youtube.com/watch?v=X", wantErr: ErrInvalidURL}, } diff --git a/internal/web/page_landing.templ b/internal/web/page_landing.templ index b87e187..d93db8f 100644 --- a/internal/web/page_landing.templ +++ b/internal/web/page_landing.templ @@ -75,9 +75,9 @@ templ landingFormats() { @iconUploadLink() - Ссылки на YouTube -

Или прямой URL на файл записи — скачаем сами.

- youtube.com · прямые ссылки + Ссылки на YouTube и X +

Вставьте ссылку на видео — запись скачаем сами.

+ youtube.com · x.com
diff --git a/internal/web/page_landing_templ.go b/internal/web/page_landing_templ.go index a15553c..551fdb2 100644 --- a/internal/web/page_landing_templ.go +++ b/internal/web/page_landing_templ.go @@ -212,7 +212,7 @@ func landingFormats() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " Ссылки на YouTube

Или прямой URL на файл записи — скачаем сами.

youtube.com · прямые ссылки
опционально
PDF с презентацией

Приложите слайды отдельным файлом — вставим их в нужные темы конспекта.

опционально
Слайды из видео

Если отдельной презентации нет — найдём кадры со слайдами прямо в записи.

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " Ссылки на YouTube и X

Вставьте ссылку на видео — запись скачаем сами.

youtube.com · x.com
опционально
PDF с презентацией

Приложите слайды отдельным файлом — вставим их в нужные темы конспекта.

опционально
Слайды из видео

Если отдельной презентации нет — найдём кадры со слайдами прямо в записи.

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/web/page_upload.templ b/internal/web/page_upload.templ index 1fe7067..ca81046 100644 --- a/internal/web/page_upload.templ +++ b/internal/web/page_upload.templ @@ -78,9 +78,9 @@ templ UploadPage(data LayoutData) {
-

Поддерживаются YouTube и прямые ссылки на аудио/видео.

+

Поддерживаются видео с YouTube и из публичных постов X.

Поддерживаются YouTube и прямые ссылки на аудио/видео.