Замечания и предложения по нему, а также их обсуждение. Предыдущий тред >>1000000.
>>/b/1003098 Раньше не было возможности escape-ить символы разметки, теперь есть. Раньше на ***%%You are a buggy fork!%%*** Кусаба выводила ломаный HTML, <b><i><spoiler></spoiler></b></i>, ибо ** имеет приоритет над *, и возник вопрос, что делать в ситуации, когда встречаем тэг, закрывающий блок верхнего уровня, а внутренние блоки ещё не закрыты. A. Закрывать все внутренние блоки по тэгу закрытия блока верхнего уровня. ***%%*** => <b><i><spoiler></spoiler></i></b><i>; A++. По закрытию, восстанавливать незакрытый внутри закрываемого блока контекст. ***%%*** => <b><i><spoiler></spoiler></b><i></i>; B. Сделать приоритет тэгов разметки контекстно-зависимым, чтобы ***%%You are a buggy fork!%%*** интерпретировалось как [b][i]%%You are a buggy fork!%%[/i][/b]. Или ***%%*** => <b><i><spoiler></spoiler></i></b> Вариант A позволяет написать You are a buggy fork! как ***%%You are a buggy fork!**, что короче и потенциально удобнее. Варианты A++ и B имитируют, как было раньше. Вариант A было меньше кодить, потому и был реализован. Но, если нужно, могу к началу января взяться сделать совместимость. Который из вариантов больше по душе?
***%%You are a buggy fork!%%***
<b><i><spoiler></spoiler></b></i>
**
*
A.
***%%*** => <b><i><spoiler></spoiler></i></b><i>
A++.
***%%*** => <b><i><spoiler></spoiler></b><i></i>
B.
[b][i]%%You are a buggy fork!%%[/i][/b]
***%%*** => <b><i><spoiler></spoiler></i></b>
***%%You are a buggy fork!**
>>1000358 Поспав на этом два дня, думаю, что можно, технически, просто добавить пример со спойлером в раздел Markdown->Особенности (и поставить туда якорь, чтобы ссылаться удобнее). Но я думал над тем как сделать Совусу кодоподсветку, и знаете, было бы неплохо внести наши изменения в апстрим. И тогда Совусу наверное захочется совместимость, и чтобы теги не закрывались по концу сообщения а игнорировались наверное? Я попробую потыкать до рождества и сам и его что кому надо. Но если говорить про фичи, можно придумать вообще кнопку текстового превью поста? Решает вообще все текущие и будущие проблемы с разметкой, если пользователь может починить всё сам. Ещё можно заморочиться и аж в постформе это делать по ходу заполнения текста, но это или часто дёргать движок, или переписывать то же самое по второму разу на жс.
>>1000368 > И тогда Совусу наверное захочется совместимость Скорее всего. A++ вариант к нему ближе всего. Кусаба parse'ит ***Жирный**Курсив* как ЖирныйКурсив, after all. Хотя не идентичен: скажем, **text* Кусаба распарсит как *text, но не текущий алгоритм. Чтобы, как Кусаба, нужно вводить lookahead до закрывающего тэга. Который ещё может оказаться в [nofmt] блоке, и который должен будет игнорироваться поэтому. И который если не найдётся, должен будет привести к reparsing'у того would-be открывающего ** как *. > и чтобы теги не закрывались по концу сообщения а игнорировались наверное И это тоже. И тут тоже нужно искать закрывающий тэг. В любом случае, похоже, стоит отказаться от parsing'а в один проход. Скажем, можно разбить ввод на токены, инактивировать незакрытые тэги, убрать пустые блоки, и уже потом делать HTML. Можно сделать и lookahead-зависимый **/* parsing, но это куда муторнее.
***Жирный**Курсив*
**text*
> можно придумать вообще кнопку текстового превью поста? Why not. Если силы есть. > или переписывать то же самое по второму разу Даёшь Flower Bus на Node.js!
>>/b/1003427 > 300x100 Поднимаем баннер?
>>1000377 Сначала пусть кто-то нарисует.
>>1000378 ??
>>1000377 Миленько, но кто это там на самолёте?
>>1000380 Pea Ace (Горошина-Ас) же!
Пытались что-нибудь трогать? > И который если не найдётся, должен будет привести к reparsing'у того would-be открывающего ** как * Любопытная циклическая лабуда в оригинальной Кусабе. '' => ''; '*' => '*'; '**' => '**'; '***' => '*'; '****' => '**'; '*****' => '*'; '******' => ''; // <b><i></b></i> Если приставлять звёздочки к 'text*' и 'text**' период тоже 6, но свой. Наверное, нет смысла такое поведение копировать? А то как бы не получилось, что последовательное применение регулякок со strtr-ом выйдет не только на несколько сотен строк кода меньше, но и быстрее. Пускай, наверное, будет '****' => '', то бишь <b></b>. В конце концов, оригинальный parser не убирает возможность отправить пустое сообщение, either. Тогда, пусть будет '***' => '***', '***t*' => '**t' '***t**' => '*t' и '***t***' => 't'. Пустые же блоки дополнительным проходом поубирать.
Стоит сделать обновление RSSа по удалению поста. >>/b/1003583
>>1000385 Что там обновлять? Если такое сообщение попало в кеш твоего ридера то сервер с ним уже ничего не сделает.
>>1000385 Done. >>1000386 RSS обновлялся только по постингу новых постов.
>>1000370 Силы на это нашлись, прикрутить перевод после нескольких попыток не нашлись. >>1000377 Done.
>>1000383 Если '****' это <b></b>, то почему *** не <i>*</i>? Алсо, '***t**' => '<b>*t</b>' или *<b>t</b>? По идее наверное первое?
'****'
<b></b>
***
<i>*</i>
'***t**' => '<b>*t</b>'
*<b>t</b>
> Done. Cool. >>1000389 > почему *** не <i>*</i>? У позиции 0 распознаётся **, поскольку имеет приоритет над *, и parsing идёт дальше. У позиции 2 * распознаётся как *, но ни для раннего **, ни для * не находится закрытие. Поэтому оба инактивируются и печатаются, как есть. Reparsing'а у позиции 0 не происходит. Если бы происходило, было бы <i></i>*, и было бы '**' => ''. > По идее наверное первое? Да. Если саму систему parsing-а пока не трогали, напишу новый BBCode() тогда. Где-то к началу января будет готово. Как-то так пока вижу. Оставляем continue-проверки только для кода/nofmt и для \n\r-тэга закрытия списка, а также для открывающего BB-тэга, если ровно тот же тэг пока не был закрыт, i.e. в '[i] [i] [/i]' второе [i] вызывает continue, '[i] [i] [/i]' => ' [i] '. Встречаем тэг? Добавляем его в список, а также простой текст между ним и предыдущим тэгом. Вместо true в $states пишем ссылку на свежедобавленный элемент списка. Встречаем закрывающий тэг? Из $states, если есть, по ссылке достаём соответствующий открывающему тэгу элемент списка, и прописываем туда ссылку на закрывающий элемент. Вторым проходом инактивируем незакрытые тэги, третьим делаем HTML, следя, чтобы '* [i] test * [/i]' и подобное не приводило к некорректному HTML: '* test0 [i] test1 * test2 [/i]' => ' test0 test1 test2 '.
> к началу января Или к середине.
>>1000391 Да это я думаю пока не критично, хоть и хорошо было бы. Я сам-то в разъездах до 12го.
Всё-таки течёт оно у меня невероятно. И без раскрытых картинок. И наверно, получается, проблема уникальная для этой конфигурации, раз больше никот. Какая-то несовместимость может. Ои на месте, а версия с sw всё поднимается и поднимается.
>>1000402 Не совсем понимаю, как это читать. Это всё местное, и заодно течёт не только воркер? Ну и на всякий случай тот же вопрос про 410. Так-то я могу себе вернуть/поставить тоже рикай и помониторить.
>>1000403 Я тоже не понимаю, как это читать, лол. Эото скриншоты с девтулсов, открытых на вкладке именно тут. Просто тыкнул что-то с надписью memory как очевидное, а там почему-то экстеншоны. Воркера не видно было, но единственное отличие 0141 от 014 в нём, поэтому на него и грешу. Вот сейчас рикая нет, а вкладка опять 200,000 K и растёт дальше пока пишу этот пост. Открыл /b/ 410 сейчас, прокрутил сверху донизу, открыл quick reply, попечатал, развернул картинку на 4000×4000, подождал. Около 70,000 K, стабильно, (норма). Быстрый тест булки (поставил sleep 5m) - так же. Попробовал Clear site data в Devtools (и Unregister service workers которая там). Всё равно отъелась до 400,000K просто постояв открытая. В общем, мистика. Сделать тут мало что можно, так как подозреваю всё-таки какую-то непонятную несовместимость с моей уникальной конфигурацией. Но мне хотелось бы узнать, сколько у вас вкладка потребляет просто постояв. Может, у вас много памяти свободно и вам просто незаметно. А я тут постоянно на границе OOM сижу. Месяц непрерывно запущенного хрома это не шутки, собсно, там сам Browser утекает, а кнопки Minimize mem usage, как в Firefox, не завезли.
Как-то так на моей лисе. Наверное, действительно течёт где-то. >>1000404 > но единственное отличие 0141 от 014 в нём Не единственное же. Есть изменения в kusaba.js.
>>1000405 Это очень долгий замер! У меня за пять минут все улетает. Ну и в "лисе", а надо на хромиум-подобных!
>>1000406 Или не течёт. Проверю в хромиуме чуть позже.
На TaskManager-е в Хромиуме memory footprint действительно растёт, но и периодически сбрасывается. Наверное, дело в сборке мусора.
Memory Snapshot за 5 минут, однако, ничего интересного не показывает.
>>1000391 Новости. У меня депрессия. tokenize → fix_integrity → print почти готово, оставалось бы только отдебажить, но поскольку [nofmt] и [code] сами по себе являются escaper'ами, для них нужно будет делать предобработку отдельным циклом и таки с lookahead'ом, и уже потом дотокенезировать гарантированно непокрытый активными [nofmt] или [code] блоками текст. Завис пока на этом. Иначе, как пока сейчас у меня в черновике, будет вывод «every mark after unclosed ` is **ignored** ». А должно быть «every mark after unclosed ` is ignored"». Also, погодя возник вопрос, что делать, если, скажем, для незакрытого [code] встречаются за-escape'ленные и escape-блоком другого типа, и тильдою [/code], например «[code] This is `NOW ~[/code]`». Думаю резолвить такой ввод как «[code] This is NOW ~[/code]» всё-таки. Другие заметки по надвигающемуся. Будет пофикшена ситуация (±костыльно, но можно будет включить и цитирование в обобщённую обработку)List end.> Citation Будет пофикшена ситуация %% - Bug. %% ↓↓↓↓↓↓↓ Bug.
NOW ~[/code]
>>1000410 Поправляйтесь. Ради развлечения, попробовал чисто теоретически сформулировать грамматикой. Выходит как-то не очень: Message => List\nMessage|Quote\nMessage|Paragraph\nMessage|EOF List => OrderedList|UnorderedList OrderedList => OLElement\nOrderedListContinuation|OLElement OrderedListContinuation => OLElement\nOrderedListContinuation|OLElement OLElement => +InlineParagraph|#InlineParagraph UnrderedList => ULElement\nUnorderedListContinuation|ULElement UnorderedListContinuation => ULElement\nUnorderedListContinuation|ULElement ULElement => -InlineParagraph|*InlineParagraph InlineParagraph => Line|Line~\nInlineParagraph Line => NoFmtLine,Line|CodeLine,Line|BoldLine,Line|ItalicLine,Line|UnderscoreLine,Line|StrikethroughLine,Line|AsciiLine,Line|SpoilerLine,Line|URL,Line|Text,Line|<empty> NoFmtLine => [nofmt]Text,NoEscape[/nofmt]|``Text,NoEscape`` CodeLine => [code]Text,NoEscape[/code]|`Text,NoEscape` BoldLine => [b]Line,NoEscape[/b]|**Line,NoEscape** ItalicLine => [i]Line,NoEscape[/i]|**Line,NoEscape** UnderscoreLine => [u]Line,NoEscape[/u] StrikethroughLine => [s]Line,NoEscape[/s]|^^Line,NoEscape^^ AsciiLine => [aa]Line,NoEscape[/aa] SpoilerLine => [spoiler]Line,NoEscape[/spoiler]|%%Line,NoEscape%% NoEscape => (~~)*|Text,(~~)* Text => [^\n]*? URL => (http|https|ftp|sftp|mailto)://[^, \n]+ Paragraph => NoFmtParagraph,Paragraph|CodeParagraph,Paragraph|BoldParagraph,Paragraph|ItalicParagraph,Paragraph|UnderscoreParagraph,Paragraph|StrikethroughParagraph,Paragraph|AsciiParagraph,Paragraph|SpoilerParagraph,Paragraph|Line,Paragraph|<empty> NoFmtParagraph => [nofmt]MLText,NoEscape[/nofmt]\n? CodeParagraph => [code]MLText,NoEscape[/code]\n? BoldParagraph => [b]\n?Paragraph\n?,NoEscape[/b]\n? ItalicParagraph => [i]\n?Paragraph\n?,NoEscape[/i]\n? UnderscoreParagraph => [u]\n?Paragraph\n?,NoEscape[/u]\n? StrikethroughParagraph => [s]\n?Paragraph\n?,NoEscape[/s]\n? AsciiParagraph => [aa]\n?Paragraph\n?,NoEscape[/aa]\n? SpoilerParagraph => [spoiler]\n?Paragraph\n?,NoEscape[/spoiler]\n? MLText => Text\nMLText|Text|\n|<empty> Хорошо что мы вложенные списки пока не даём.
>>1000411 А, ну и >>ссылки забыл добавить на одном уровне с урл и определить Quote как >Line. (или InlineParagraph?)
>>1000410 Готово. parse.class.php и markdown.html в архиве. Запилено, как оговорено, Кусаба-подобное поведение, пофикшено упомянутое в >>1000410 и >>/b/1004023 пофикшено тоже. Обработка (">", "\r\n") обобщённым токенизатором привела к конфликту с >>post_id, который был решён запихиванием обработки этого >>post_id в общий же токенизатор: как следствие, внутренние ссылки теперь подлежат escape-у. Возможно, стоит запихать в него же и обработку внешних ссылок, что может быть удобно, если хочется поместить ссылку под спойлер. InterboardQuoteCheck и InterthreadQuoteCheck я не трогал. Наверное, можно как-то красиво сжать определения констант, но я не стал заморачиваться. Часть debug_* функций я не стал удалять. Вдруг пригодятся.
> Поправляйтесь Спасибо. > чисто теоретически сформулировать грамматикой Тоже вот думалось, можно ли как-то это дело формально определить и скормить Bison-у, и чтобы оно само всё сгенерировало. Но у нас, вполне возможно, не context-free grammar. > Хорошо что мы вложенные списки пока не даём Scary.
>>1000413 It's up!
>>1000410 Мужик сказал — мужик сделал. Круто и ответственно!
Добавил URLы в обобщённую обработку. Теперь можно escape-ить начало URLа по ~. Условия, по которым терминируется URL, отличаются от оригинала.Пробельный символ;~ (поглощается);.,:;?!«»“”’… перед пробельным символом или в конце строки;Текст, соответствующий любому из тэгов разметки.То бишь, нет терминации по скобкам: чтобы отправить "Автобус (https://410chan.org/b/)" нужно будет набрать "Автобус (https://410chan.org/b/~)". Убрал возможность делать ссылки с ftp://-дескриптором, потому что FTP выпилен из современных браузеров, но там легко в url_start_subregex и в mark_to_mark_type по аналогии добавить. >> у >>post_link теперь тоже опознаётся через mark_to_mark_type, и токенизируется тем же, что и внешние ссылки, кодом. На будущее, должно быть легко g://here_goes_gelbooru_hash и p://pixiv_artwork_id добавить. Можно даже без префиксов-дескрипторов сделать. [nofmt] и `` теперь не превращают пробелы в неразрывные. Файлы в архиве.
.,:;?!«»“”’…
Also, надо бы поменять тип message столбца с text, на mediumtext. И на Чио тоже. Когда длина сообщения будет считаться по mb_strlen, вызвать переполнение будет даже проще, чем сейчас.
>>1000417>Firefox 90 will no longer support the FTP protocolОднако.
>>1000419 https://kb.mozillazine.org/Register_protocol Но есть такое вот. Так что, наверное, стоит поддержку ftp:// вернуть. Заодно ftps и sftp добавить. Может, ещё что-то? Также, если есть возможность как-то проверять, есть у протокола handler или нет, можно будет добавить в kusaba.js, чтобы по клику на ссылку происходило её копирование в случае, если нет.
>>1000417 Добавлено, но: 1. Оставил mailto, ftp, news 2. Оставил декодирование ссылок как было чтобы не нарваться на XSS из прошлого года >>1000418 TODO. Как и обновить код на кодберге. Ещё надо наверное проверить есть ли изменения в рендере от смены пробелов неразрывных на обычные в коде.
>>1000423 2. Я там убрал htmlspecialchars decode, потому что теперь не вызывается htmlspecialchars encode перед parsing-ом, prettify_url оставив тем же. Иначе получается, как на приложенной картинке. > есть ли изменения в рендере от смены пробелов неразрывных на обычные в коде.Я только для [nofmt] и для `` убрал. Не для [code] и `. Если убрать их и для [code], оно съест отступы.
BTW, если по запилу кодоподсветки оформлять развод, то, наверное, стоит и [nbsp] добавить.
Перетащу сюда всякое в видный пост чтобы не терялось. >>1000340 якорь добавить-перекрасить. >>1000344 sodane отдельным скриптом(?) >>1000402 попробовать это отладить. При желании можно костыль-версию добавить и включать или одно или другое по каким настройкам... Было бы ещё неплохо для модерки какой экран просмотра анимапчи...
>>1000418>>1000425 Done.
>>1000428 Gut. >>1000427> Было бы ещё неплохо для модерки какой экран просмотра анимапчиСписок, где слева картинка, справа — имена, и можно редактировать? > При желании можно костыль-версию добавить и включать или одно или другое по каким настройкам...Есть версия, которая не использует SharedWorker, поскольку тот не реализован в мобильном Хроме. Можно if(!!window.SharedWorker) поменять на if(false) и посмотреть, в нём ли дело.
if(!!window.SharedWorker)
if(false)
>>1000429 И кнопочку аплоада/разрешения для какой доски. Или два разных экрана, один для алиасов, один для доскопринадлежности. Так можно избавиться от текстофайлов и их в БД держать.>Можно if(!!window.SharedWorker) поменять на if(false) и посмотреть, в нём ли дело.А я пожалуй так и сделаю.
> $catalog_page .= '<span class="catalogmsg">' . closeOpenTags(mb_substr(strip_tags(stripslashes($line['message'])), 0, 40)) .'</span><br />';> closeOpenTags(mb_substr(strip_tags(stripslashes($line['message'])), 0, 40))С учётом HTML Entities, получать catalogmsg можно вот так, наверное. function get_catalog_msg($msg, $max_catalog_msg_length){ $catalog_msg = ''; $msg_id = 0; $catalog_msg_len = 0; $brs = ['<br>' => 1, '<br/>' => 1, '<br />' => 1]; while($msg_id < strlen($msg) && $catalog_msg_len < $max_catalog_msg_length){ $c = $msg[$msg_id]; if($c === '<'){ $html_tag_term_id = strpos($msg, '>', $msg_id); if($html_tag_term_id === false) break; if($html_tag_term_id - $msg_id + 1 <= strlen("<br />")){ $maybe_br = substr($msg, $msg_id, $html_tag_term_id - $msg_id + 1); if(array_key_exists($maybe_br, $brs)){ $catalog_msg .= ' '; $catalog_msg++; } } $msg_id = $html_tag_term_id + 1; } else if($c === '&'){ $html_entity_term_id = strpos($msg, ';', $msg_id); if($html_entity_term_id === false) break; $html_entity = substr($msg, $msg_id, $html_entity_term_id - $msg_id + 1); $decoded = html_entity_decode($html_entity, ENT_QUOTES | ENT_HTML5); if($html_entity != $decoded){ $catalog_msg .= $html_entity; $catalog_msg_len++; } $msg_id = $html_entity_term_id + 1; } else{ $o = ord($c); // we're at the start of some UTF-8 symbol if($o > 0xDF) $bytes = $o > 0xEF ? 4 : 3; else $bytes = $o > 0x7F ? 2 : 1; $catalog_msg .= substr($msg, $msg_id, $bytes); $catalog_msg_len += 1; $msg_id += $bytes; } } return $catalog_msg; }
function get_catalog_msg($msg, $max_catalog_msg_length){ $catalog_msg = ''; $msg_id = 0; $catalog_msg_len = 0; $brs = ['<br>' => 1, '<br/>' => 1, '<br />' => 1]; while($msg_id < strlen($msg) && $catalog_msg_len < $max_catalog_msg_length){ $c = $msg[$msg_id]; if($c === '<'){ $html_tag_term_id = strpos($msg, '>', $msg_id); if($html_tag_term_id === false) break; if($html_tag_term_id - $msg_id + 1 <= strlen("<br />")){ $maybe_br = substr($msg, $msg_id, $html_tag_term_id - $msg_id + 1); if(array_key_exists($maybe_br, $brs)){ $catalog_msg .= ' '; $catalog_msg++; } } $msg_id = $html_tag_term_id + 1; } else if($c === '&'){ $html_entity_term_id = strpos($msg, ';', $msg_id); if($html_entity_term_id === false) break; $html_entity = substr($msg, $msg_id, $html_entity_term_id - $msg_id + 1); $decoded = html_entity_decode($html_entity, ENT_QUOTES | ENT_HTML5); if($html_entity != $decoded){ $catalog_msg .= $html_entity; $catalog_msg_len++; } $msg_id = $html_entity_term_id + 1; } else{ $o = ord($c); // we're at the start of some UTF-8 symbol if($o > 0xDF) $bytes = $o > 0xEF ? 4 : 3; else $bytes = $o > 0x7F ? 2 : 1; $catalog_msg .= substr($msg, $msg_id, $bytes); $catalog_msg_len += 1; $msg_id += $bytes; } } return $catalog_msg; }
キタ━━━(゚∀゚)━━━!!
>>1000434 Ахаха ох вау.
>>1000435> $to_append = strtr($to_append, [" " => " ", "\t" => " "]); Забыл ; добавить.
>>1000436 Поправлено. >>1000433 Хммм. Вообще, было бы неплохо это через formatLongMessage сделать что уже делает примерно то же самое. И парсер хтмл заново писать не надо, потому что он либу использует.
formatLongMessage
>>1000437 Теперь там просто DomDocument->loadHTML->getNode->textContent, и всё в mb_substr. Алсо, оказывается всё время с ввода нового formatLongMessage оно выводило лишние <!DOCTYPE><html><body></body></html>, лол. >>1000430 Так и сделано. >>1000402 прожмите F5 и проверьте, пожалуйста.
DomDocument->loadHTML->getNode->textContent
mb_substr
>>1000437 Стоит, думаю, и посты поправить. update posts_b set message=regexp_replace(message, ' (?!;)', '\\1 ') where postedat > unix_timestamp('2025-02-17 08:23:40') and postedat < unix_timestamp('2025-03-04 08:47:55'); update posts_d set message=regexp_replace(message, ' (?!;)', '\\1 ') where postedat > unix_timestamp('2025-02-17 08:23:40') and postedat < unix_timestamp('2025-03-04 08:47:55'); >>1000438> Теперь там просто DomDocument->loadHTML->getNode->textContent, и всё в mb_substr.В formatLongMessage или вместо closeOpenTags(...)?
update posts_b set message=regexp_replace(message, ' (?!;)', '\\1 ') where postedat > unix_timestamp('2025-02-17 08:23:40') and postedat < unix_timestamp('2025-03-04 08:47:55'); update posts_d set message=regexp_replace(message, ' (?!;)', '\\1 ') where postedat > unix_timestamp('2025-02-17 08:23:40') and postedat < unix_timestamp('2025-03-04 08:47:55');
closeOpenTags(...)
>>1000439 Не особо любо менять посты, но так как это был баг, то ладно. И да, в closeOpenTags. То есть там теперь не мешанина из striptags()stripslashes()closeopentags() а просто берётся текстовая часть хтмл и обрезается до 40 символов.
Спустя долгие месяцы разработки, анонимная кармочка наконец-то запилена! Теперь вы можете проголосовать, насколько каждый пост "девочка", "булочка" или "кот" и накрутить этот рейтинг, передёргивая роутер! Кто знает, может самые популярные посты за месяц получат настоящую булочку??
>>1000445 Жалко, что основного пропонента идеи нет. На телефоне несколько за-missalign'уто выглядят новые кнопки по вертикли по отношению ко кнопке быстрого ответа. Нету padding-а меж кнопкой быстрого ответа и девочкой, можно промахнуться. Также, custom_tags, может быть, стоит переносить целиком на следущую строку, если не влазит. Или, по крайней мере, сделать, чтобы иконка и соответствующее ей значение переносились вместе. Девочка, булочка и кот в качестве счётчиков — удачное решение. А вот с SVGшками сложнее. Кот получился довольно удачно. Или сравнительно удачно. Девочка скорее похожа на кролика. Рот крестиком, будто зашитый. Булочка не Sternsemmel. Круассан? Сложно SVGшки делать. Пытался вот для тонущего треда сделать иконку с кораблём, но хорошо не получается. В /b/ при переходе на каталог кидает сообщение про JSON parsing error.
>>1000446> Нету padding-а меж кнопкой быстрого ответа и девочкой, можно промахнуться.Вроде, достаточно поставить пробел перед custom_tags span-ом, но в ОП-постах он уже есть. Думал вот ещё, может сделать float: right для того span'а, но всё-таки при разномастной ширине постов лучше выглядит так, как есть.
>>1000446 Ну, может ещё заглянет, пока будет висеть. По css сложно~. Но перенос запретить емнип можно. Пробел в ОП-посте из-за того что там и других кнопок добавлено порядком. Попробовал ещё один для всех.>Булочка не Sternsemmel. Круассан? Да. Может попытаюсь переделать.>Пытался вот для тонущего треда сделать иконку с кораблём, но хорошо не получается.Там обычно просто якорь. Будет убрано к выходным, версия в виде юзеркрипта скорее всего попозже.
>>1000417 УРЛ в УРЛе сломан немного: >>>/b/1004405
>>1000456> УРЛ в УРЛе сломан немногоИз url_end_regex убрать '|' . 'https?:\/\/'。> >>>/b/1004405В tokenizer_regex сделать '|' . '>>(?=[\/0-9])' вместо '|' . '>>'。 По идее, должно заработать.
'|' . 'https?:\/\/'
'|' . '>>(?=[\/0-9])'
'|' . '>>'
Попытался слепить тут с кавалерийского наскоку, лол. По-моему смотрится только gold версия.
И ещё вариант.
>>1000458 Можно попробовать ротацию сделать. >>1000459 Лапы UGR, конечно, далеко тянутся...
>>1000458 Красненькое-то где.
>>1000460 Выбрать надо!>UGRUniversidad de Granada? Unified Girls Registry? >>1000461 Красненькое не нужно. Обновленные цвета отражают приверженность бренда нашей имиджборды целям построения лучших коммуникативных стратегий со своей аудиторией.
>>1000462 У нас линк на пост и кнопка ответа и пиктограмки в углу всё красненькое.
>>1000463 А gold фона и фона постов больше по площади!
>>1000461 Действительно, не по-умночански, выбивается. Но так ли это плохо? Если сделать ротацию (случайный выбор при генерации HTML), то будет смотреться хорошо, наверное. Лучше, чем если целый ряд заглушек одной картинкой представлен. Хотя вариант в цветах Умночана я бы всё же добавил. И, наверное, все заглушки кириллицей лучше подписывать.
>>/b/1004436 скобку съело.
>>1000466 В оригинале было, что можно для ссылок типа Викепедийных …Сервал_(Персонаж) скобки, но я скобки разрешил, как часть URL в целом: чтобы получить (https://pixiv.net) нужно набрать (https://pixiv.net~). Если продолжат спотыкаться об это изменение, сделаю «умную» систему терминации URL по скобке. Но можете и сами сделать. Код с регулярками в архиве по >>1000417.
(https://pixiv.net~)
Смотрю, а это в faq/markdown упомянуто. Ну ладно, раз уж документировано, то my fault.
Докрасил таки.
Против добавления всех сразу ничего не имею.
>014.cdn.ganbaranai.moe
>>1000472 годы-то_30-ые.рика_нипа.jpg
Есть тут вот у меня желание запилить-таки ротацию спойлеров (по MD5 файла, наверное) и после, может быть, отдельное поле в БД для сажи — с Соусным значком или иначе, но у меня пропала локальная копия с изменениями. В связи с чем прошу опубликовать текущую версию движка. Но может, стоит прежде смёржить текущие изменения с 410, что, правда, не без лишней мороки будет: счётчик символов Соус в репу так и не закоммитил, например. Единственно что, шрифт с засечками, может быть, оставить стоит. Ну и на счёт красной кнопки отправки я не совсем уверен. Хотя вот с учётом наличия кнопки предпросмотра, может, в цветовой диференциации будет смысл. Может быть, текст кнопок этих в будущем на значки заменить? Предпросмотр на моей мобилке на вторую строчку перелезает. С другой стороны, оно и без той кнопки перелезает: (новая на одной строчке, а нить) на другой, а с той кнопкой хотя бы словосочетание не разрывается: на телефоне, может стоит обе кнопки на новую строку тогда?
>>1000476 >>1000476 Красная кнопка имхо вырвиглазна. Но другое смержить стоит.>по MD5 файла, наверноеДа можно и по рандому после таймстампа. Я просто не очень представляю как сделать это не ломая текущий функционал. Лезть в дебри CSS3 и через image(attr())?
image(attr())
>>1000477> Я просто не очень представляю как сделать это не ломая текущий функционалА там что-то серьёзно ломается? Я когда в июне пытался приступить к делу, там такое обстоятельство было, что картинка для спойлера задаётся через ::after, который придётся сделать настоящим отдельным элементом. В остальном не помню, чтобы там какие-то ещё проблемы были. А чуть-чуть JS и стили поредактировать, чтоб заработало, — это не страшно, наверное.
>>1000479 Не хотеть ЖС, хотеть чтобы изкоробки работало.
>>1000480 Моя тоже хотеть и будет делать, но раз было сказано, что функционал ломается, я предположил, что, может, изменения DOMа что-то в kusaba.js поломали бы. Как там оно на самом деле — посмотрим.
>>1000430 >>1000402 Прошло полгода, никаких известий о том течёт или больше не течёт. Возвращено назад.
>>1000476 Изменения синхронизированы и выборочно импортированы.
>>1000483 Спасибо. Может, к воскресенью что-то уже готово будет.
>>1000477 Сделал через '<img class="spoiler-holder" src="' . TimestampToSpoiler() . '"></img>'. Патч в архиве. Варианты добавлять в директорию css/spoilers. По изменению вариантов, перегенерировать страницы. > image(attr())MDN говорит, что url(attr()) нельзя. https://developer.mozilla.org/en-US/docs/Web/CSS/attr#limitations_and_security Можно было бы, наверное, выкрутиться через background-image: if(mod(attr(), --spoiler_count), ..., ...) но писать-тестировать толпу вложенных if-ов мне лениво: насколько я понимаю, array'ев, switch'ев и map'ов в CSS нет. Как и нет substr, так что всё равно board-post.class.php менять пришлось бы. Чтобы только через CSS, можно выкрутиться через селекторы. .catalogpic.spoiler-image:has(:is(img[src*="0s."],img[src*="1s."]))::after, .spoiler-image.imglink:is(a[data-full-src*="0."],a[data-full-src*="1."])::after { background-image: url('/css/spoilers/spoiler-koromo.png'); } .catalogpic.spoiler-image:has(:is(img[src*="2s."],img[src*="3s."]))::after, .spoiler-image.imglink:is(a[data-full-src*="2."],a[data-full-src*="3."])::after { background-image: url('/css/spoilers/sp-test-gold-cyr.png'); } …и так далее. С одной стороны, централизованно всё и в случае добавления/удаления спойлеров не нужно тратить время на регенерацию всех HTML досок и тредов. С другой, не знаю, скажем, 11 разных спойлеров и 100 таких правил… Convoluted это несколько. Хотя если helper скрипт сделать, который такой spoilers.css по содержимому директории spoilers автоматически генерит, наверное, не страшно. Если CSS-only вариант нравится больше, думаю, стоит при генерации HTML добавлять отдельный attribute с timestamp'ом: поддержке :has вроде всего два года как.
'<img class="spoiler-holder" src="' . TimestampToSpoiler() . '"></img>'
css/spoilers
url(attr())
background-image: if(mod(attr(), --spoiler_count), ..., ...)
.catalogpic.spoiler-image:has(:is(img[src*="0s."],img[src*="1s."]))::after, .spoiler-image.imglink:is(a[data-full-src*="0."],a[data-full-src*="1."])::after { background-image: url('/css/spoilers/spoiler-koromo.png'); } .catalogpic.spoiler-image:has(:is(img[src*="2s."],img[src*="3s."]))::after, .spoiler-image.imglink:is(a[data-full-src*="2."],a[data-full-src*="3."])::after { background-image: url('/css/spoilers/sp-test-gold-cyr.png'); }
spoilers.css
spoilers
:has
>>/b/1004675 Думаю, стоит повесить баннер.
>>1000486 >>1000487 Обновлено, спасибо.>MDN говорит, что url(attr()) нельзя.Да, тогда ттолько оверлеем через css. >TimestampToSpoiler()Я попробую сделать что-нибудь поинтереснее, чтобы картинки не менялись от количества спойлеров. Да, базу править конечно, но щито поделать.
>>1000488> Да, базу править конечно, но щито поделать.Ну, можно отсортировать файлы-заглушки по дате-времени их создания в ФС, и выбирать по модулю только из тех заглушек, которые созданы не позже прикрепляемой картинки. Но лучше, наверное, всё-таки отдельную таблицу для этого, сделав timestamp заглушки unique. А можно никаких миграций не делать и выкрутиться, как с баннерами: заведя отдельную закртыдоску под них, скажем, spoilers. Хотя вот для баннеров Соус призывает отказаться от такого подхода. Альтернативно, можно позволить заглушкам для старых картинок обновляться и воспользоваться consistent hashing, тогда от добавления одной новой заглушки к N имеющимся вероятность того, что заглушка у картинки поменяется будет circa 1/N. Но это при условии, что порядок файлов в выдаче scandir() от добавления не поменялся. Скажем, https://arxiv.org/pdf/1406.2294 int32_t JumpConsistentHash(uint64_t key, int32_t num_buckets) { int64_t b = 1, j = 0; while (j < num_buckets) { b = j; key = key * 2862933555777941757ULL + 1; j = (b + 1) * (double(1LL << 31) / double((key >> 33) + 1)); } return b; } O(ln num_buckets) в среднем.
int32_t JumpConsistentHash(uint64_t key, int32_t num_buckets) { int64_t b = 1, j = 0; while (j < num_buckets) { b = j; key = key * 2862933555777941757ULL + 1; j = (b + 1) * (double(1LL << 31) / double((key >> 33) + 1)); } return b; }
>>/b/1004760> За-escape'ить тильдой объявление списка в данном случае нельзя. Точнее, нельзя за-escape'ить только его: вместе с ним за-escape'ится и конец цитаты. Всё-таки стоило разделить "\r\n- " и иже на два mark'а. Позволило бы более интуитивно-потятно escape'ить списки заодно, хотя, возможно, и усложнило бы кодВнезапно, всё оказалось достаточно просто. Даже проще, чем было. Теперь можно escape-ить окончание (пункта) списка и его объявление отдельно. Что позволяет escape-ить список тильдой на той же строке. >>1000411 …И что, судя по всему, без особой возни и без ввода новых элементов разметки позволяет запилить вложенные списки. Надо или нет? >>1000457 Починено. >>/b/1004763 Парсер теперь понимает и одиночные CR и LF. Надо проверить, решит ли проблему. Патч в архиве.
BTW, стоит ли вернуть GetCWebpath в inc/func/paths.php? У нас, скорее всего, из-за этого https://014chan.org/news.php ошибку 500 сейчас возвращает. Кажется, меня с manage.php тоже возникла какая-то похожая проблема, но я уже не помню точно.
>>1000492 Не стоит, проще убрать остатки использования что были пропущены в прошлый раз.
This is a test.
>>1000494Я импортировал >>1000491 но не предложенные изменения на 410.
>>1000494Должно быть починено.
Подумываю вот переделать JS posting с fetch'а на XMLHttpRequest, чтобы прогресс отображался (текстом и/или цветом а-ля progress bar). Заодно несколько расширить проверку на клиенте того, что можно: размер файла, соответствие формата файла содержимому.В связи с чем хочу несколько поменять способ, которым разные свойства передаются клиенту. Сейчас это делается через smarty, который пишет script'ы с ними в head — кроме MAX_FILE_SIZE, который в скрытом input'е под postform'ой. Под бордоинвариантные из этих свойств завести общий channel.json в KU_WEBPATH. Под бордоспецифичные — свой board.json для каждой доски. И в head тогда писать link'и к ним.Проблема с channel.json в том, что не совсем ясно, как trigger'ить его регенерацию. В config.php сравнивать дату изменения этого config.php с датой изменения channel.json? Но captcha_message вот не по config.php генерируется, а из gettext-овских файлов. Его оттуда в kusaba.js ко strings убрать?И как быть с magic numbers для форматов. Вообще, схожие определения/перечисления для типов файлов у нас сейчас распиханы по разным местам: kusaba.js, posts.php, manage.php, таблица filetypes. Хотелось бы неким образом это централизовать. Наверное, отчасти это происходит из-за нежелания делать целый запрос в базу, чтобы проверить, скажем, является ли файлорасширение картинкой или, скажем, является ли тип картинки анимируемым. Так что если генерить channel.json по config.php, наиболее простым вариантом видится выпилить таблицу filetypes и в config.php завести KU_FILETYPES, а в posts_* завести столбец allowed_filetypes с содержимым вида ".jpg.png.gif.webp", по strpos проверяя поддерживаемость.Конечно, может нарушится integrity, если в config.php формат пропадёт, а в столбце останется, но Соус не так давно сперепугу форматы поудалял, а треды в /dev/ вполне себе спокойно регенерируются, правда без thumbnail'ов-заглушек, где удалено. Однако Соус просил сделать настраиваемость определяемого в config.php через manage.php, а вынос регистрации форматов в config.php такой идее скорее противоречит.Если реализовывать Соусову идею, заменить config.php на config.json? Но не парсить же JSON при каждом вызове read.php, да и разный postprocessing для $cf[] в config.php делается. Но можно генерировать config.php на основании config.json и поставить require config.after.php в конец. В тот config.after.php добавить postprocessing и свойства, которые генерировать по JSONу не целесообразно или не хочется. Also, генерировать config.php можно ведь и не по JSONу, а по БД, где под всякие KU_CATTHUMBWIDTH завести таблицу-синглтон, оставить filetypes в БД и JSONы только для клиентов тогда. Но за актуальностью автосгенерированного config.php по config.json следить проще: если какое-то из конфигурационных значений в БД поменяется не через manage.php, должен быть механизм обновления config.php, а с config.json можно ± обойтись сверкой дат изменения. В прочем, с board.json та же проблема, если какие-то update'ы в таблице boards не через manage.php делать. В общем, некий явный механизм актуализации JSONов всё же будет нужен.Как смотрите?
require config.after.php
>>1000497>Проблема с channel.json в том, что не совсем ясно, как trigger'ить его регенерацию.Если там параметры, что можно менять в рантайме, то по сохраниению этих параметров. Если там не такие параметры, то или ставить этот json как source of truth и импортировать их в config.php, или запихивать пых в жсон чтобы импортировалось из config.php.>Хотелось бы неким образом это централизовать.Если что-то звучит как либа и крякает как либа, то возьмите готовую либу.>наиболее простым вариантом видится выпилить таблицу filetypes и в config.php завести KU_FILETYPES, а в posts_* завести столбец allowed_filetypes с содержимым вида ".jpg.png.gif.webp", по strpos проверяя поддерживаемостьЭто выпилит возможность добавлять форматы без доступа к серверу. В идеале, это надо только на тип формата, а не на каждое расширение.>Но не парсить же JSON при каждом вызове read.phpplz, мы делаем запрос к БД просто чтобы проверить что доска с таким-то именем действительно существует в самом начале файла. Завернуть конфиг в формат, предназначенный для конфига, или целиком в БД никаких значимых потерь в производительности не привнесёт.А вот делать синхронизацию которая всё равно должна будет читать жсон/БД - это тащить корову на баню.
>>/b/1004863> https://ru.wikipedia.org/wiki/Понтрягин%2C_Лев_Семёнович> %2CНа Авто/b/усе та же штука. Вроде декодирование печатаемых (>= 0x20 и не DEL) ASCII-символов не должно влиять на парсер у 410, но у нас не должно точно, так что исправил это + небольшие исправления в коде для списков.
>>1000498Пока склоняюсь к тому, чтобы в config.php импортировать config.json, сделать его source of truth и сделать его 403, а JSONы для клиентов генерировать. Предусмотреть в manage.php пункт меню для регенерации тех JSONов: чтобы, если удобнее, config.json и БД можно было отредактировать чем-то кроме manage.php и в manage.php лишь применить изменения.> А вот делать синхронизацию которая всё равно должна будет читать жсон/БД - это тащить корову на банюЯ отчасти потому config.php предложил генерировать, что какие-то строки для оптимизации через APC в config.php уже есть. И что ситуация, когда read часто, write almost never, а сравнение времени модификации файлов и проверка flock всё же более простая, наверное, операция, чем чтение их содержимого.> Если что-то звучит как либа и крякает как либа, то возьмите готовую либу.Для проверки соответствия расширения файла его заголовку можно подтянуть file или какой у PHP к нему binding, но ведь и для JS что-то нужно будет взять... Точно не overkill для ныне circa 10 расширений, где оно надо? С другой стороны, ещё удобнее будет новые форматы добавлять и для них тоже проверка будет.В целом с расширениями и информацией о них пока склоняюсь к тому, чтобы получать их из JSONа. Без SSH к серверу, пусть через manage.class.php тот JSON будет редактируемый.> read.phpВозвращаясь к нему, хочу заметить, что оно из архитектуры, где страницы каталогов, досок и тредов статичные, несколько выбивается подходом. Although, свиду оно позволяет несколько постов читать, но у нас это где-то, кроме как для внутренних ссылок, используется? Судя по inc/func/calculations.php:getQuoteIds, когда-то через запятую форматом >>0,1,2 можно было указать несколько постов, но они у нас форсированно одиночные, и вряд ли какие-то изменения предвидятся.По Traditional: read.php/board/thread/posts могу предположить, что когда-то посты были статичными файлами тоже, что было бы проще. Скажем, если запиливать внутренние ссылки на посты архивированных тредов. Но можно решить и перестав выпливать посты архивированных тредов из базы и добавив столбец is_archived.Хм, now that I look at it, вижу getArchivePostMessage в inc/func/stringformatting.php и параметр $archive_dir у formatReflink. Но у Соуса ссылки на архивные посты не работают, и по вопросу сказал, что не нужно, помнится. А у нас, если какие-то треды в архив отправлять, я бы сделал. Но не проще ли просто закрывать старые треды тогда? Перенося, может, на специально отведённую под архив доску.
inc/func/calculations.php:getQuoteIds
Traditional: read.php/board/thread/posts
getArchivePostMessage
inc/func/stringformatting.php
$archive_dir
formatReflink
>>1000500>какие-то строки для оптимизации через APC в config.php уже естьТаки да, но APC заменён на APCU ещё с седьмого Пыха, и по умолчанию выключен. Я не уверен, что многие этим пользовались. И я не вижу какого-либо способа из админки форсировать перезагрузку конфига для всех.>сравнение времени модификации файлов и проверка flock всё же более простая, наверное, операция, чем чтение их содержимогоВозможно, но это всё равно дополнительный disc read. ИМХО, если и делать генерацию, то не автоматическую, а по вызову какой команды ручками. Ну и потом встаёт вопрос, насколько сильно надо заботиться чтобы правильно-правильно все строки там экранировать, чтобы генерация точно-точно всегда работала.>но ведь и для JS что-то нужно будет взятьТут бы я тем более взял либу, на самом деле. Выставлять магические числа в json не стоит, они должны быть стандарт. Должно хватать только списка поддерживаемых MIME-типов. В идеале, если не костылить самому, то и дрифта между либами быть не должно, если они нормально поддерживают стандарт.Но нам надо костылить самим как минимум лимит на размер кадра в картинке, и количество потоков в видео. Делать это ручками очень, очень не стоит. Хотя количество потоков может можно и только серверу оставить проверять.>Для проверки соответствия расширения файла его заголовку можно подтянуть file или какой у PHP к нему bindingЯ это предлагал ещё когда на Ычан добавляли вебм, через ExifTool. Меня решили не слушать и полагаться на выхлоп ffprobe через консольку, как и в FBE потом. ЧСХ, FBE вообще не смотрит на магические числа когда генерирует уменьшенную копию, а надеется на то, что вызываемые тумбнейлеры станут противиться, если формат файла не будет совпадать с передаваемым спецификатором.Но есть вызов mime_content_type в случае если уменьшенная копия НЕ генерируется, лол. Так что зря Соус вообще архивы выпиливал из /dev/.>могу предположить, что когда-то посты были статичными файлами тоже, что было бы прощеСкорее всего, никогда не были. read.cgi был полностью динамикой, futallaby что-то странное со всего одним файлом, футабу тыкать лень. Есть Кахера, где ссылки как раз в Traditional-формате, но там это достигалось путём того что треды, как файл - просто наборы строк-постов, разделённые через \n. А собиралось всё опять-таки динамикой.В целом, в те времена не думаю что людям нравилось бы хранить пост, фактически, три раза. А то и больше с +50 и -100-страницами.>Но не проще ли просто закрывать старые треды тогда? Перенося, может, на специально отведённую под архив доску.Архив по идее и должен быть отдельной доской под каждую доску, просто автоматизировать это слегка геморрно.ЕМНИП в стандартной кусабе (или Х) архивирование вообще изкоробки сломано.
mime_content_type
>44 изменённых файлов: 713 добавлений и 1853 удаленийЯ хотел сделать менеджер для баннеров и спойлеров но отвлёкся. https://codeberg.org/yakui-lover/fbe-410/compare/kotocafe...yakui-lover/fbe-410:dev
>>1000501> Выставлять магические числа в json не стоит, они должны быть стандартСтандартные и выставлять? Стандарты-то открытые и такие важные для совместимости вещи там, думаю, вряд ли меняются. Конечно, больше мороки при добавлении file extension'ов и писать цикл с hex2bin, но это не что-то слишком страшное в обмен на отсутствие зависимостей.Но пусть будет либа.> лимит на размер кадра в картинке, и количество потоков в видео. Делать это ручками очень, очень не стоитАа. Indeed. Хотя вот размер кадра в картинке у нас проверяется разве? И надо ли? Доводилось было видеть в интеренете такую экзотику, где этот размер увеличивался по ходу видео. Если у каждого кадра может быть свой размер, то... Просто взять, и проверить все кадры? Но, например, их в 25 MiB с mp4/avc1 можно запихать не меньше миллиона точно. Предметно говоря, сконструировал видео 1x1 на 18 MiB/700 тыщ кадров; мои попытки перебрать frame=width с помощью ffprobe идут 7-11 секунд. Хотя, если прямой binding к libav подключать, скорее всего, это будет на порядок, а то и на несколько, быстрее. Если нет, ввести предел на количество кадров? Может ли быть так, что в метаданных контейнера количество кадров одно, а на деле в контейнере их куда больше? Наверное, может. То же самое с duration, который таки проверяется? Тоже, и точно можно, опять же, покадровым перебором PTS и frame duration посчитать. Непаханное поле тут на самом деле, если с точной валидацией видео заморачиваться; было бы классно, будь под этот попсовая PHPшная либа, чтобы самому с libav не возиться, но вряд ли. Хотя вот и с libav я пока только https://github.com/PHP-WebRTC/av , которое насколько поддерживаемое? Для Питона вот есть PyAV, а тут, видимо, не всё так просто. Anyhow, это если точность нужна.> Ну и потом встаёт вопрос, насколько сильно надо заботиться чтобы правильно-правильно все строки там экранировать, чтобы генерация точно-точно всегда работала.Думаю, стоило бы. BTW, надо ли для config.json простенький inc/func/acid.php, где atomic_read($path) и atomic_write($path, $data) с семафорами и восстановлением? Или просто лочим config.json в manage.class.php при редактировании?Ещё такой вот вопрос. В config.php к параметрам стоят комментарии и параметры эти разбиты на секции с описанием.Можно эту схему прямо в config.json, рядом со значениями, добавлять и удалять их в случае чего удобнее, но код для чтения значений в $cf[] будет менее эффективен.'type': 'section','desc': 'Database','vars': [ { 'name': 'KU_DBHOST', 'value': 'localhost', 'type': 'string', 'desc': 'Database hostname' }, ...]Но можно генерировать config.values_only.json. Можно разделить это на config.json, где будут только 'KU_NAME': '014chan' и config.schema.json. Или, как вариант, всю мету над значениями определять и handle'ить прямо в manage.class.php. Что больше нравится?>>1000502Уборка тоже хорошее дело же.Мы точно совсем-совсем не хотим Аобин escape_sql? Я не пользовался (или его ещё тогда не написали? не помню), но можно начать, некое удобство в том, наверное, есть... Хотя вот выпилить KU_DBPREFIX, предположу, с ним сложнее оказалось. Но поддерживать-то вряд ли сложно. Ну, или Аобу же и можно попросить, если контакты остались.
atomic_read($path)
atomic_write($path, $data)
'type': 'section','desc': 'Database','vars': [ { 'name': 'KU_DBHOST', 'value': 'localhost', 'type': 'string', 'desc': 'Database hostname' }, ...]
'KU_NAME': '014chan'
P.S. libav refers to libavcodec and other libav* that are part of FFmpeg to distinguish them from FFmpeg executables. Not to the dead libav fork of FFmpeg.
>>1000507>Хотя вот размер кадра в картинке у нас проверяется разве?Ага. Вроде и правда не проверяются. В Вакабе точно есть.>И надо ли?Желательно, особенно при увеличенных лимитах на загрузку. Иначе https://github.com/liclac/pngbomb.Но это только(?) png. С видео проблем быть не должно таких.Заморачиваться с точностью duration... при наших объёмах постинга наверное непринципиально. Всё запощенное всё равно просматривается, и врушничать с этим мало что кому даст.При больших объёмах постинга скорее наверное имеет смысл какая-нибудь периодическая батчевая оффлайн-проверка?>Или просто лочим config.json в manage.class.php при редактировании?ИМХО flock() должно быть достаточно для этих целей, да. Оно и так должно быть достаточно быстро. В крайнем случае tmpfile->mv.>config.schema.jsonЭто лучше и так можно валидировать конфиг перед попыткой его записи (или чтения, или отдельной командой). JSON Schema вполне себе давно стандарт.>Мы точно совсем-совсем не хотим Аобин escape_sql?Я его поддержал потому что мне было лень этим заниматься, а ему нет. С момента https://codeberg.org/FBE410/fbe-410/issues/33 прошёл год, и теперь мне не так сильно лень.Плюс я всё-таки хочу использовать рано или поздно Постгрес, для этого нужен будет PDO в любом случае. И даже без него, prepare->execute->fetch для меня привычнее писать. А там где ты используешь prepare, escape_sql уже и не нужен. Плюс, если его оставлять, то неплохо бы добавить поддержку float, blob, NULL (ни %s, ни %d корректно не данный момент это не обрабатывают), и чтобы %B вызывало аналог Board::verify_board_name мною добавленного а не регексп на [a-z]. Или хотя бы заменить на [^`/], потому что имя борды может быть довольно большим набором символов.Оно в отдельном коммите, реверснуть дело не хитрое. Выиграет тот кто переведёт все вызовы под свой стиль раньше.
>>1000509>Иначе https://github.com/liclac/pngbomb.И вся защита у людей сводится к "не открывайте слишком большие (по количеству пикселов) файлы в памяти", да. Помимо "никогда не запускайте imagemagick на одной системе с сервером и правами сервера".
>>1000509> https://github.com/liclac/pngbomb.Аа, вылетело из памяти. Лол.https://www.kernel.org/doc/gorman/html/understand/understand016.html#htoc101Теоретически, наиболее вероятно, что по out of memory Линух просто убьёт процесс, который генерируя thumbnail сожрал всю память, а не Apache, MariaDB или что-то важное. Так что интересно, насколько это в действительности страшно. С одной, наверное, не смертельно. С другой, a system running out of memory может тормозить до глюков, и проще вызвать DoS.>>1000510> И вся защита у людей сводится к "не открывайте слишком большие (по количеству пикселов) файлы в памяти"У imagemagick точно нет эффективного thumbnailer-а, который декодирует исходную картинку по частям? Вроде у PNG хранить декодированные линии дальше предыдущей не обязательно. JPEG поделён на блоки 8x8. С I-frames у видео сложнее, там блоки бывают разного размера: WebP top to bottom rendering поддерживает, а вот AVIF нет. Но с AVIF не ясно, потому ли это, что какая-то важная информация хранится в конце файла, или потому, что зависимости между блоками в самых разных частях картинки или ещё что-то сложное.Насколько целесообразно вместо или совместно с лимитом на пиксели сделать imagemagick'у и ffmpeg'у лимит на память? Через ulimit, systemd-run, timeout или иначе. Заодно и лимит на время поставить? В конце концов, гигантские картинки попросту долго обрабатывать. А в случае, скажем, с JXL — не только гигантские; пока Google поставил на нём крест, но кто знает.> При больших объёмах постинга скорее наверное имеет смысл какая-нибудь периодическая батчевая оффлайн-проверка?Можно так. А можно собирать некую статистику и при низкой нагрузке позволять постить экзотически большие файлы, whether пикселями, количеством кадров или чем-то ещё.> Но это только(?) png. С видео проблем быть не должно таких.https://litter.catbox.moe/u06p8y4eby61w3gb.avif20000 по высоте и ширине. 17 килобайтов. AV1 поддерживает размерность до 65536 по одной стороне и 12bpc. Конкретно AVIF также поддерживает прозрачность. К сожалению или к счастью, FFmpeg'овский IMGUTILS при попытке что-то FFmpeg'ом с картинками такого размера сделать или сгенерировать такие размеры фильтрами, говорит, что size invalid, так что продемонстрировать WebM на 20000x20000 не могу. Но можно попробовать найти-поменять захардкоженные константы и рекомпилировать или сделать через aomenc --webm.BTW, у нас ведь есть поддержка анимированных thumbnail'ов. Lossy WebP не поддерживает yuv444p и позволяет кадры только до 16384 по стороне, но, вполне возможно, закодированными такие кадры тоже достаточно невесомые, чтобы их в одном файле можно было отправить тысячу или две.
>>1000511Ну, я для демонстрации знакомому докер-процесс прибивал таким. Хотя там ж Докер, там наверняка и общей памяти немного, и он всё равно перезапустится через пять секунд.>У imagemagick точно нет эффективного thumbnailer-а, который декодирует исходную картинку по частям?По крайней мере за секунду не гуглится, но есть выставление лимитов если делать через пых, а не сискаллом: https://www.php.net/manual/en/imagick.setresourcelimit.php>Через ulimit, systemd-run, timeout или иначе.Можно и так, да.Но это ж надо напрягаться и помимо админства бордочки из инсталлятора ещё и систему заадминить, ха. Хотя вон Ханабира с vargrant-файлом в комплекте шла. И kusaba.js вообще в Докере.
> https://codeberg.org/yakui-lover/fbe-410/pulls/4> +9063 -44418Вот это похудение..Но пока, наверное, рано?Пофиксив синтаксические ошибки в api_adaptive.php и inc/classes/randword.class.php, ./vendor/bin/phpstan analyse --memory-limit 8G -cignore.neon -l1 inc lib *.php даёт 34 ошибки.> ignore.neonparameters: ignoreErrors: - '#Function _gettext not found#' - '#Function _getText not found#' - '#Function _textdomain not found#' - '#Function _setlocale not found#' - '#Function _bind([_a-z0-9])* not found#' - '#Constant KU(_[A-Z0-9]*)* not found#' - '#Variable \$.* might#' excludePaths: - inc/classes/mark.phpНесколько опечаток в названиях переменных/функций.Часть конструкторов/функций вызывается без нужного количества аргументов или вызывается с большим, чем объявлено.Часть вызываемых функций пытаются сослаться на переменные (объявленные вне их тела?) (но так и было?).Часть функций should return .* but return statement is missing (но это потому, что там return в if'е?).Висит mark.php от Котобы, наверное, стоит удалить.В posting.class.php в CheckFaptcha на 219-ой "$this->board_class->board_dir" не в {}. phpstan на это почему-то не ругается. Статический Анализатор, лол.Оставлена финская локаль. (Эйля горячо одобряет.)Это, наверное, лучше не про сейчас, но что нам даёт gettext такого, чего не даст inc/lang/$locale.json?
./vendor/bin/phpstan analyse --memory-limit 8G -cignore.neon -l1 inc lib *.php
parameters: ignoreErrors: - '#Function _gettext not found#' - '#Function _getText not found#' - '#Function _textdomain not found#' - '#Function _setlocale not found#' - '#Function _bind([_a-z0-9])* not found#' - '#Constant KU(_[A-Z0-9]*)* not found#' - '#Variable \$.* might#' excludePaths: - inc/classes/mark.php
should return .* but return statement is missing
>>1000513>Вот это похудение..Большая часть всё же от вывода Smarty в подтягиваемую либу.>Часть вызываемых функций пытаются сослаться на переменные (объявленные вне их тела?) (но так и было?)Я попробовал прибить везде global, но может быть не везде/часть наследует объявление от импорта.>что нам даёт gettext такого, чего не даст inc/lang/$locale.json?Более стандартный интерфейс, наверное? Но так как мы и так используем либу вместо встроенного, то как удобнее.Но жсон-вариант я ещё ни разу не видел.
С qutebrowser(который webkit) постоянно Old faptcha is old. Please renew, и не важно включены кукисы\жава или нет.
>>1000515Без печенек оно работать и не будет, да, оно через PHPSESSID ведётся.Проверьте после включения и прокликивания фапчи что оно у вас выставляется и не сбрасывается в новое значение после попытки постинга?
>>1000516Сработало после смены content.cookies.accept never на no-3rdparty.А нельзя ли его без кукисов заставить работать?
>>1000517Можно. Переписав механизм работы с PHPSESSID на БД. Только у вас тогда будет отваливааться капча при смене айпишника.Заниматься я этим ближайшее время, конечно же, не буду.
>>/b/1005072Спойлеры в (18837, 18840, 18841, 18965, 19000, 19021, 19022, 19030, 19033, 19048, 19067, 19074, 19084, 19102, 19109, 19158, 19167, 19182, 19216, 19259, 19282, 19291, 19325, 19373, 19392, 19429, 19432, 19451, 19456, 19475, 19480, 19501, 19524, 19551, 19557, 19558, 19559, 19577, 19581, 19585, 19599, 19602, 19603, 19642, 19691, 19692, 19716, 19825, 19836, 19846, 19927, 19929, 19931, 19933, 19935, 19936, 19941, 19942, 19944, 19961, 19995, 20020, 20028, 20037, 20038, 20039, 20041, 20043, 20044, 20051, 20055, 20057, 20059, 20080, 20082, 20085, 20087, 20090, 20092, 20093, 20109, 20112, 20122, 20123, 20125, 20126, 20128, 20129, 20130, 20144, 20148, 20150, 20152, 20157, 20162, 20165, 20166, 20167, 20173, 20174, 20178, 20201, 20219, 20254, 20301, 20307, 20319, 20322, 20334, 20355, 20359, 20417, 20425, 20435, 20437, 20443, 20445, 20447, 20459, 20506, 20557, 20565, 20571, 20575, 20577, 20579, 20587, 20589, 20597, 20605, 20607, 20608, 20613, 20628, 20644, 20647, 20648, 20668, 20673, 20683, 20686, 20688, 20696, 20697, 20715, 20717, 20718, 20720, 20741, 20745, 20748, 20756, 20783, 20848, 20852, 20887, 20913, 20993, 20994, 20998, 21006, 21026, 21058, 21070, 21072, 21105, 21106, 21151, 21154, 21161, 21164, 21191, 21267, 21277, 21292, 21298, 21315, 21350, 21370, 21404, 21406, 21477, 21490, 21494, 21546, 21557, 21579, 21630, 21641, 21654, 21733, 21749, 21750, 21808, 21814, 21844, 21910, 21911, 22031, 22039, 22158, 22174, 22179, 22270, 22279, 22310, 22316, 22317, 22318, 22319, 22370, 22376, 22427, 22435, 22454, 22455, 22579, 22595, 22617, 22619, 22626, 22637, 22643, 22670, 22679, 22684, 22697, 22714, 22715, 22720, 22721, 22722, 22759, 22764, 22765, 22766, 22767, 22770, 22777, 22781, 22782, 22785, 22787, 22789, 22794, 22796, 22797, 22813, 22821, 22826, 22833, 22834, 22841, 22851, 22852, 22860, 22876, 22884, 22890, 22891, 22900, 22927, 22928, 22929, 22931, 22940, 22943, 22973, 22974, 22993, 22994, 22996, 23001, 23002, 23003, 23004, 23005, 23012, 23023, 23042, 23043, 23044, 23045, 23046, 23051, 23052, 23053, 23054, 23055, 23073, 23108, 23117, 23134, 23140, 23141, 23152, 23184, 23190, 23191, 23226, 23228, 23231, 23282, 23303, 23347, 23352, 23364, 23402, 23413, 23417, 23427, 23514, 23516, 23521, 23553, 23575, 23606, 23615, 23694, 23698, 23707, 23716, 23793, 23796, 23839, 23870, 23885, 23886, 23887, 23890, 23903, 23904, 23923, 23969, 23975, 24081, 24146, 24153, 24156, 24163, 24165, 24170, 24173, 24218, 24250, 24276, 24285, 24295, 24300, 24360, 24367, 24368, 24445, 24490, 24496, 24553, 24574, 24588, 24589, 24616, 24628, 24690, 24776, 24845, 24909, 24947, 24958, 25098, 25099, 25100, 25101, 25109, 25117, 25133, 25134, 25135, 25201, 25242, 25336, 25342, 25347, 25354, 25357, 25378, 25453, 25454, 25472, 25500, 25585, 25586, 25597, 25646, 25647, 25684, 25833, 25875, 25876, 25896, 25905, 25915, 25918, 25923, 25951, 25956).На булочке был удалён файл в >>/b/25341.В идеале стоило бы, наверное, проверить, какие из удалённых постов импортировались, и удалить. Но у меня, вполне возможно, несколько постов из удалённых тоже живы в базе, так что со 100%-ной точностью не получится. Надо?
Похоже, что пересоздание страниц не пересоздаёт thumbnail'ы. >>/b/25864. Наверное, стоит удалить их для файлов, запощенных на Булочке за последние несколько месяцев, и перегенерировать страницы.
>>1000526>пересоздание страниц не пересоздаёт thumbnail'ыС чего бы оно это делало, уменьшенная копия генерируется всего один раз, при загрузке.
>>1000527> уменьшенная копия генерируется всего один раз, при загрузкеПохоже, что-то не так с моей памятью. Прошу прощения за вредный совет.Thumbnail'ы параметризуются по размеру и анимированности. На случай изменения этих параметров какой-то механизм для регенерации мог бы быть. Или если corruption случится.BTW, где-то на задворках сознания у меня крутится идея провести реформу thumbnail'ов: сейчас артефакты сжатия бывают довольно заметны при увеличении интерфейса до удобочитаемости на моём ноутбуке. Увеличить s'кам качество. Перевести, может, все thumbnail'ы на WebP. Взять более медленный метод сжатия, чем сейчас. Сделать, чтобы как и в случае с PNG, для VP8L thumbnail'ы тоже были lossless. Или PNG перевести на lossy? I wonder.
>>1000517Если без кукисов и не по IP, то разве что скриптами. Видится два варианта и как-то так:Первый будет загружать JS'ом капчу, сохранить PHPSESSID в переменной и добавлять его в cookie при отправке. Можно user script'ом. Как понять, когда PHPSESSID всё, а клиент думает, что оно живое? Dunno, но, скорее всего, можно.Второй — шлём вместе с капчей шифрованный на неё ответ + timestamp, по успешному решению возвращаем токен на постинг с закодированным timestamp'ом. Но тогда проще вайпать, ибо таких токенов на постинг можно намайнить тьму, и не очень понятно, как без IP вести какой-то контроль за их выдачей/аннулированием. Вводить PoW? От атакующего, арендовавшего десяток EPYC'ов, не спасёт. Хотя от такого атакующего текущая защита всяко инвалидна; тут разве что по аномалии вводить белые списки IP на постинг.У PHPSESSID же скорее всего есть какие-то ограничения на количество на IP и количество в целом. Таким образом, если привязывать капчу только к IP, то легче установить, есть ли другая ойчанька с тем же IP, чем если оставить всё, как оно есть.Так что думаю, лучше найти, как в браузере сделать белый список сайтов, которым можно хранить печеньки. Хром вот в такое из коробки умеет, помнится. Под qutebrowser, возможно, расширение какое-то есть.
Из JS-функционала про капчу, который действительно стоило бы запилить, мне видится синхронизация капчи между вкладками: чтобы по открытию новой вкладки с формой постинга, капча на других вкладках обновилась ею. Иначе открываешь в процессе чтения треда А тред Б, возвращаешься к треду А, пишешь туда ответ, а тебе говорят, что капча не правильная.Ещё, для фапчи сделать, чтобы при JS постинге ответ на неё отправлялся отдельно--без поста с файлом в 10 MiB.
ЖС это глупость. Не стоит на неё лочить функциональщину.
Некоторые патчи к текущему HEAD'у dev ветки.Дальше попробую заставить ссылки на посты работать; проблемы и с постингом, и с read.php. Наверное, уберу таки Inter(board|thread)QuoteCheck, по проверке поста на существование, сделаю post link через formatQuote, которое пока игнорирует KU-традиционный-что-то-там и тип борды.С read.php, стоит ли его упростить, убрав неиспользуемый функционал для чтения множества постов?
>>1000533Ну, раз у меня развязаны руки экспериментировать и дальше, то можно и в /dev/. >С read.php, стоит ли его упростить, убрав неиспользуемый функционал для чтения множества постов?Хмм. У меня есть подозрение что оно ещё может использоваться на текстодосках. Как-нибудь.Я в выходные приму патч и ещё поиграюсь с предлагаемым phpstan, да.Если интересно, я тестирую на кусаба.якуж.мое.>>1000525И спасибо, да.>В идеале стоило бы, наверное, проверить, какие из удалённых постов импортировались, и удалить.Раз булка опять онлайн, я могу попробовать снова утащить базу.>>1000528Но тогда это и не импорт. Meh. А если это и не импорт, а что-то лучшее, то можно и домен обратно на 0141 или котокафе или вообще правила править.>>1000529Можно ещё всю форму ответа сделать на динамике, чтобы она шла с айдишником капчи в скрытом поле.>Ещё, для фапчи сделать, чтобы при JS постинге ответ на неё отправлялся отдельно--без поста с файлом в 10 MiB.Формально, и текстовая капча может быть адаптивной, и фапча неадаптивной. Но ЕМНИП это указывается или в печеньках или в коде страницы.
>>1000534> У меня есть подозрение что оно ещё может использоваться на текстодосках.Вряд ли. Когда-то может и использовалось — когда (судя по getQuoteIds) через запятую можно было указать несколько постов, но ни у Соуса, ни у нас в parse.class.php такой ввод not recognized. Только в *QuoteCheck функциях и по разным файлам частично код для поддержки остался. Проще окончательно выпилить. Понадобится, тогда уже и думать о добавлении.> можно и домен обратно на 0141 или котокафеХотел было написать, что by this point я не очень против, но есть следующие возражения. Баннеры у нас по большей части про 014 — в частности, и те несколько, которых нет на Булочке. Ещё, во избежание конфуза с доменами, возможно, лучше оставить как есть. Кто-то было жаловался, что что-то с индексированием у поисковиков случилось по прошлой смене домена.> или вообще правила правитьЕсть какие-то соображения по? Наготу без спойлера разрешить?> и текстовая капча может быть адаптивной, и фапча неадаптивнойФапча — да, текстовая капча, помнится, нет и мне было пришлось менять код, чтобы её таковой сделать. Но я про то, чтобы если капча введена неверная, пользователю сразу бы приходило оповещение о том и не приходилось ждать, пока пост загрузится на сервер.> Можно ещё всю форму ответа сделать на динамике, чтобы она шла с айдишником капчи в скрытом поле.Indeed. Жаль, что HTML imports не живы. Судя по всему, было непродолжительное время, когда через <template is=""> и <link href="postform.php"> можно было бы такую динамику и без JS, и без embedded PHP сделать.
<template is="">
<link href="postform.php">
PHP внепланово обновлён до 8.4.
>>1000543> The uploaded file exceeds the upload_max_filesize directive (2M) in php.ini.
Also, делали ли какие-либо правки после применения патчей? Или, когда я починю ссылки, можно спокойно к 0010-Fix-autoformatter-messed-up-vars-declarations присылать?
>>1000545Ещё нет.Присылайте, мерж-конфликт исправить не сложно.
>>1000544И вроде пофикшено.Зря оно не пытается конфиг скопировать, хм.
>>1000539>Проще окончательно выпилить.Тогда согласен.>Кто-то было жаловался, что что-то с индексированием у поисковиков случилось по прошлой смене домена.Можно впилить обратно поиск, ха. Только в dev он уже почти выпилен.>Есть какие-то соображения по?Ну или явно запретить если без спойлера. Добавить пару слов о главенстве формы над содержанием, что как бы более явно разрешит писать о большем, чем. В то же время явно вписать разжигание политики в правила.
В set_inputs скобку забыли у getCookie() вызова.
getCookie()
>>1000549fixed.
>>1000550> {el.value = getCookie('name'}Иие. Скобка не на том месте добавлена.
{el.value = getCookie('name'}
>>1000551
Tfw всё так >>/b/1005149 и случилось.