RSS
# Re: Солнечный сентябрь
pipe.2032
vit01(mira, 1) — boscholeg
2020-09-30 16:27:58


boscholeg> Бывают студенты балбесы и лодыри, а бывают наоборот трудоголики без тормозов. Вторые часто слетают с нарезки.

Из трудоголиков только 1 человека знаю. Остальные "полетели" по личным причинам, с учёбой не связанными совсем

+++ Отправлено через IDEC Mobile
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Солнечный сентябрь
pipe.2032
boscholeg(ping,5) — vit01
2020-09-28 10:48:06


Про дурку и жертв тяжкой учебы я неоднократно слышал в приложении к Химфаку МГУ. Думаю, что подобное возможно в любом серьезном ВУЗЕ и истоии про такое есть там. Бывают студенты балбесы и лодыри, а бывают наоборот трудоголики без тормозов. Вторые часто слетают с нарезки. Тут важно, чтобы близкие приглядывали и друзья товарищи тоже не закрывали глаза на это.

# Солнечный сентябрь
pipe.2032
vit01(mira, 1) — All
2020-09-26 16:57:40


Вот не могу писать про что-то одно, поэтому здесь будет мешанина, как всегда.


## По учёбе

Из предметов сейчас:

- Физическая кинетика (сложный, но интересный предмет, возимся с характеристическими и производящими функциями и с теорией вероятностей)
- Физика плазмы (доп. главы)
- Физика Солнца (+ лабораторные, где мы программируем на языке IDL, для которого есть астрономические библиотеки)
- Общие лабораторные работы по методам исследований в астрофизике
- Физика ближнего космоса (пока что повторение инфы с предыдущих курсов, но уже куча формулок, и мне это нравится)

Дополнительно с кафедры теорфиза я хожу на астрофизику и на теорию излучения, но там чисто как вольнослушатель и не всегда, потому что по расписанию с остальными парами они пересекаются. В любом случае, вся инфа доступна, и в виде литературы её можно осваивать самому.

Кроме этого, у нас планируется практика на телескопах. Нас свозят на несколько телескопов, а кое-куда даже на пару дней с ночёвкой. По мере прохождения практики буду присылать сюда подборки фотографий, это наверняка будет красиво и прикольно. Самый настоящий солнечный сентябрь =)

[celestia-s-sun.jpg]( https://www.deviantart.com/mysticalpha/art/Celestia-s-Sun-16-10-510690495 )

## Прогресс по статье

Как я рассказывал в предыдущем солнечном посте, следующим этапом исследования было начать смотреть размер и форму радиоисточника. Насколько он большой или маленький, в каких местах больше или меньше светится. Для этого всего лишь требовалось увеличить его хорошенько и рассмотреть поближе.

https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/RiAPBBsQa2jG7BOQb2dg

А можно ещё побольше увеличить и нарисовать контуры по яркостной температуре.

https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/7P4b96E12t63vphc1t4i

Радиотелескоп работает абсолютно по-другому, нежели фотокамера. Он составляет своё изображение не тупо в виде "пикселей", а в виде кусочков синусоид. В итоге сырое изображение до обработки является огромным месивом из (как правило) крестообразных ярких пучков. После обработки (алгоритм CLEAN) побочные максимумы дифракционной картины отсекаются, а главный максимум остаётся. В итоге изображение составляется уже из размытых пятен, где в центре самый яркий пиксель, а ближе к краям - менее яркие. Я хотел отрендерить образец "пятна" для радиогелиографа Нобеяма, но было лень, поэтому не стал =) Просто представьте себе кусочек распределения Гаусса в голове, окей?

Так вот, отвлёкся. Поскольку изображение составляется из пятен-гауссиан, то сравнивать размер светящегося источника имеет смысл именно с этим пятном, а не тупо в пикселях считать. В итоге я взял площадь радиоисточника на полувысоте от максимума и сравнил с такой же площадью пятна телескопа на полувысоте. Получилось, что в течение дня размер активной области меняется как-то так:

https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/vAuA1J1e0mzgybiFPu1D

Вообще говоря, на графике выше есть некоторая загадка. Когда я сравнивал его со значениями максимальной яркостной температуры, то никакой толком корреляции не обнаружил, хотя она там должна быть. Эту загадку надо решить или объяснить, почему мой алгоритм работает не так. Но для этого нужно построить данную кривую для всех событий, а не для нескольких (и кое-что отсмотреть вручную). Но ничё, я ж типа "исследователь", поэтому делать загадочное незагадочным и есть моя работа.

Изображения, кстати, очень тяжёлые, и для построения одного такого графика с жёсткого диска считываются гигабайты информации.

А вот гистограмма по относительным размерам радиоисточника и пятна. Рассматривались значения площади источника, делённой на площадь пятна.

https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/z9A7IoqzEmiNx4OkWwN5

Ещё я дополнил некоторые данные по таблице в русскоязычной версии своей курсовой работы, а именно таблицу результатов примерными данными по магнитным полям, которых недоставало.

## Крутая диаграммочка для курсача

Когда возникла необходимость отчитываться перед кафедрой о своей научной работе на русском языке, мне потребовалась диаграмма, где примерно изображались этапы работы по исследованию. Что делает простой человек, когда ему надо нарисовать диаграмму? Правильно, заходит в свой любимый офисный пакет, например, LibreOffice или Microsoft Office. Кто-то более продвинутый запускает векторный графический редактор вроде Inkscape и делает там. Однако, они все совершают одну ошибку - данные программные пакеты плохи для диаграмм, потому что мышкой невозможно идеально позиционировать элементы относительно друг друга. К тому же, если вдруг что-то захотелось поменять, то очень долго будет переделывать.

Но я поступил поумнее и воспользовался специальным языком программирования для диаграмм, который называется [GraphViz Dot]( https://graphviz.org/documentation/ ). С ним не пришлось никуда тыкать мышкой, а на выходе очень быстро появилась красивенькая схема со стрелочками и ровно расположенными блоками. Оформление - одно удовольствие.

https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/IMXXpPhzPf5GEE1Yxk0a

Исходник на языке Dot:

digraph C {
    graph[rankdir=LR]
    node[shape=box, fontname="Fira Mono", fontsize=11, fixedsize=true, width=4];
    
    stages[shape=plaintext, label="Этапы работы", fontsize=14]
    data[shape=plaintext, label="Данные", fontsize=14]
    
    scan1[label="Автоматическая фильтрация"]
    result1[label="Предварительные кандидаты в гирорезонанс", color="wheat", style=filled]
    
    manual[label="Визуальный анализ"]
    result2[label="Готовые кандидаты в гирорезонанс", color="lightgreen", style=filled]

    stat[label="Статистический анализ"]

    scan1 -> result1;
    result1 -> manual;
    manual -> result2;
    result2 -> stat;
    
    {rank=same stages scan1 result1 manual result2 stat}
    
    imgs1[label="Радиоизображения (40 мин)\nКорреляционные кривые", width=3, height=0.5]
    imgs2[label="Радиоизображения (5 мин)\nКорреляционные кривые\nМагнитограммы\nРентгеновский поток", width=3, height=1]
    
    scan1 -> imgs1;
    imgs1 -> scan1;
    
    manual -> imgs2;
    imgs2 -> manual;
   
   stages -> scan1 [color="white", arrowhead=none];
   data -> imgs1 [color="white", arrowhead=none];
    {rank=same data imgs1}
}

Также, огромная благодарность создателям инструмента [Jupyter Dot Kernel]( https://github.com/laixintao/jupyter-dot-kernel ), потому что именно благодаря ему стало так просто и удобно оформлять подобные диаграммы прямо через Jupyter Notebook/JupyterLab. А вот мой научный руководитель для оформления диаграмм использует язык [PlantUML]( https://plantuml.com/ ). Этот язык очень похож на Dot и по сути выполняет такие же задачи, но имеет какие-то свои фишки. Возможно, кого-то заинтересует. А ещё есть шикарный [Mermaid.js]( https://mermaid-js.github.io/ ), который я внедрил бы кое-куда у себя.

## По работе над собой

Как было написано в предыдущем посте, решил начать инвестировать (время и деньги) в улучшение своего внешнего вида. Пара друзей мне с этим согласились помочь. Они потихоньку подбирают мне гардероб, который я так же потихоньку скупаю на свои скромные сбережения, помогли со средствами для ухода за кожей, дальше надо будет сделать хорошую причёску, копить деньги на аксессуары (надеюсь, что накоплю на что-нибудь умное и полезное, а не просто чтобы производить впечатление). Как только изменения в стиле дойдут до определённой точки, придётся ещё идти наращивать мышцы.

Некоторую старую и непригодную для ношения одежду сдал на утилизацию, и это круто (не выбрасывать же). Положительным побочным эффектом оказалось то, что освободилось место в квартире, и мне теперь гораздо проще искать в завалах именно ту одежду, которую я буду носить в данный момент. Наконец-то ещё обувь отсортировал и теперь практически полностью контролирую свои вещи в квартире. Но ещё есть, над чем работать.

На онлайн-знакомства полностью забил и пока не планирую к ним возвращаться, по крайней мере, до существенных изменений в своей внешности. Для хорошо составленного профиля ещё следовало бы фотосессию организовать, но до этого пока очень далеко.

## Физфак и матфак

Один преподаватель на 1 курсе говорил нам наполовину в шутку, что каждый год на потоке в физическом факультете кто-нибудь попадает в психушку. Сейчас я учусь на 4 курсе и знаю как минимум 3-х людей с нашего потока, которые стояли на учёте у психиатра и проходили медикаментозное лечение, и ещё парочку, которые лечение не проходили, но им точно пора в дурку.

Недавно преподавательница по лабам рассказала, что она с матфака, и что на матфаке каждый год кто-то совершает самоубийство. Надо выяснить у знакомых математиков, правда это или нет.

## Делимся расписаниями

Не так давно мы с одним товарищем по переписке решили провести эксперимент по взаимной синхронизации своих расписаний, написанных в org-mode. Так как товарищ не понимает по-русски, я перевёл файл с расписанием на английский и теперь пользуюсь org-mode почти полностью на английском.

Выводы:

- Старайтесь придерживаться какого-то одного часового пояса, потому что org-mode не умеет автоматически подстраивать файл с чужими часовыми поясами под местное время. У нас, кстати, так не вышло, потому что мой партнёр пользуется UTC, а я - местным временем
- Если у вас большие расписания, либо взаимной синхронизацией пользуются несколько человек, то содержимое org-agenda разрастается. Поэтому лучше выбрать отображение календаря (Agenda) по 1 дню или по 1 неделе. Лично мне всегда было удобнее отображать 2-недельное расписание, но не в этом случае
- Пришлось разделить всё на несколько org-файлов: жизненные цели, расписание по учёбе, краткосрочные планы + дневник, заметки. Раньше я пользовался на постоянной основе только первыми двумя

## Cron в Python'e, но зачем?

Недавно выяснил, что есть одна прекрасная Python-библиотека под названием [Schedule]( https://pypi.org/project/schedule/ ), которая позволяет реализовать планировщик по типу Cron, но только для запуска внутренней функции. Можно задать периодичность выполнения какой-то внутренней процедуры, оставить скрипт включённым, и процедура сработает в нужное время. Полезно для создания мониторинг-ботов, работающих в реальном времени.

Лично я рекомендую использовать его в связке с библиотекой [Timeloop]( https://pypi.org/project/timeloop/ ), которая запускает отдельный поток и ставит функцию на регулярное срабатывание. Будете писать какого-нибудь телеграм-бота с longpoll-процессингом - скажете спасибо.

И пример, куда же без него:

import schedule
from timeloop import Timeloop

schedule.every().day.at("21:00").do(wakeup_notify, "Одно уведомление")
schedule.every().sunday.at("9:00").do(wakeup_notify, "Другое уведомление")

tl = Timeloop()
@tl.job(interval=datetime.timedelta(seconds=60))
def process_timings():
    schedule.run_pending()

tl.start(block=False)

while True:
    bot.polling() # бесконечный цикл вашего бота

## Рекомендации по софту, неплохо бы закинуть

Иногда люблю советовать здесь в блоге интересный софт. В этот раз порекомендую программу для симуляции задачи N тел - [Симулятор физики частиц]( https://f-droid.org/packages/com.tss.android ). А порекламирую я её, потому что она появилась в F-Droid и имеет интересную графику. В данной программе можно создать звёздную систему, в центре которой будет звезда или чёрная дыра определённой массы и другие тела, которые (изначально) вращаются вокруг неё. А дальше можно посмотреть эволюцию системы и даже повлиять на неё в реальном времени, добавляя лишние тела и гравитацию.

https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/X92LvKkYsB0pu4gJj4iB

Ещё среди приложений для физиков-любителей в F-Droid есть программа [phyphox]( https://f-droid.org/packages/de.rwth_aachen.phyphox ), которая позволяет получать доступ к датчикам смартфона вроде магнитометра или гироскопа и снимать с них сырые данные для последующего изучения и проведения опытов. Думаю, для многих она будет даже более интересна, чем предыдущая, потому что о наличии некоторых интересных датчиков в своих смартфонах многие люди даже не догадываются.

## Продолжение следует

В следующем посте будет про практику на телескопах, про мою нелюбовь к фотографированию, про особенности одиноких и неодиноких людей в общении с окружающими и про подготовку к публикации. Пишу просто чтобы не забыть, это удобно =)

Этот пост в блоге: https://blog.alicorn.tk/posts/sunny-september.html

# Re: Фантастические консоли и где они обитают
develop.16
btimofeev(tavern,13) — johnbrown
2020-09-26 13:53:33


johnbrown> Там, какой-то высокоуровневый ассембер, как я понял, используется, надеюсь будет полегче. Давно хотел приобщиться. Вчера читал руководство по нему, про звуки ничего не нашёл, думал не поддерживает вообще. Ну, здорово, что консоль реально существовала, не фэнтези )

Она реально не существовала. Chip-8 больше похож на Java или современные виртуальные консоли, это была типа виртуальная машина которая проигрывала игры написанные на этом простеньким ассемблере. А распространялось это на несколько разных компьютеров тех лет.

Ассемблер там простой, я писал небольшую статью с примерами и разбором кода как выводить изображения и обрабатывать события клавиатуры, если интересно можешь почитать https://emunix.org/post/writing-chip-8-emulator-part-3/

# Re: Фантастические консоли и где они обитают
develop.16
johnbrown(ping,9) — btimofeev
2020-09-26 12:55:06


> Я когда-то интересовался одной из первых подобных платформ, разработанной еще в 70-х годах - CHIP-8. Там всего два цвета на экране, разрешение 64х32, 16 кнопок клавиатуры, из звуков только "Бииип" и игры пишутся на ассемблере. Но игры конечно простенькие - пинг-понг, арканоиды и подобное. Я учился азам написания эмуляторов на этой системе - вот тут мой эмулятор лежит https://github.com/btimofeev/emuchip

Там, какой-то высокоуровневый ассембер, как я понял, используется, надеюсь будет полегче. Давно хотел приобщиться. Вчера читал руководство по нему, про звуки ничего не нашёл, думал не поддерживает вообще. Ну, здорово, что консоль реально существовала, не фэнтези )

У меня когда-то был Микроша, но получалось запускать на нем только бейсик, да ещё какой-то текстовый редактор. Там и ассемблер был, но для меня тогда это было что-то инопланетное.

# Re: Пишу ноду ii/idec на go
idec.talks
hugeping(ping,1) — Peter
2020-09-26 12:05:55


Там от меня ушли 7 сообщений из черновиков/неотправленных? мобильного клиента... Нужно их блеклистить:

ii://2NszlFTgvhakzz7dIfvc
ii://Q03NcPZRuqeaOT5d6Tze
ii://v48ZAPJMiFbWl68YiFWU
ii://5JdRzlDtEJTfOtKCtTb4
ii://pEtdZQ4aPz7SAhFK3zwR
ii://SglNQOG3vyujcZLXjDtu
ii://flYuqUgR5SVgybdnYnVp

Извините. :)

# Re: Фантастические консоли и где они обитают
develop.16
hugeping(ping,1) — johnbrown
2020-09-26 08:49:01


Если мне захочется "живого" железа, я скорее всего выберу спектрум. В детстве я программировал на БК0010-01, а вокруг были спектрумы. Поэтому, интересно. :) Даже читал книгу по железу спека не так давно. Но реально, не уверен что руки дойдут. Много всего. :) Сейчас вот Plan-9 увлёкся.

А в плане виртуальных консолей, PICO8 для меня лучшая. В ней есть баланс ограничений, которые (на практике проверил) идеально для меня подходят. Жаль, что закрытая только. Но хотя бы формат игр открыт и есть открытые плееры...

# Re: Настройки idec mobile
idec.talks
vmg(tavern,32) — vit01
2020-09-26 08:33:16


vit01> Просьба отписаться всем остальным, кто пользуется клиентом, каков расход батареи
Расхода нет.
vit01> ну и доп. инфа, что за мобила, какая версия ОС и.т.п.
SM-n900, Android 7.1.2, LineageOS-14.1-20200911-unofficial-ha3g

# Re: Фантастические консоли и где они обитают
develop.16
btimofeev(ping,6) — johnbrown
2020-09-26 06:36:16


Я когда-то интересовался одной из первых подобных платформ, разработанной еще в 70-х годах - CHIP-8. Там всего два цвета на экране, разрешение 64х32, 16 кнопок клавиатуры, из звуков только "Бииип" и игры пишутся на ассемблере. Но игры конечно простенькие - пинг-понг, арканоиды и подобное. Я учился азам написания эмуляторов на этой системе - вот тут мой эмулятор лежит https://github.com/btimofeev/emuchip

# Re: Настройки idec mobile
idec.talks
vit01(mira, 1) — johnbrown
2020-09-26 04:18:52


johnbrown> Заметил довольно большой расход заряда - чуть больше 6% на дефолтных настройках.

Просьба отписаться всем остальным, кто пользуется клиентом, каков расход батареи

ну и доп. инфа, что за мобила, какая версия ОС и.т.п.

+++ Отправлено через IDEC Mobile
+++ GNU/Linux, Android, physics, MLP:FIM

# Фантастические консоли и где они обитают
develop.16
johnbrown(ping,9) — All
2020-09-25 18:16:12


Изучаю, время от времени, консоли из этого списка: https://github.com/paladin-t/fantasy

Приглядываюсь, прицениваюсь, так сказать. Тики, Пики, Лики... Хочется низкоуровневой 8-битной экзотики на асме или чтобы вообще без кода. Думал уже ничего не может быть проще Битси. Оказалось, может.

PIX64. Это такой no-code в "пейнте". А может и не в "пейнте". Ну, то есть, берем мышку, создаем 64x64 png, и оно как-то там само все движется...

Осталось только найти для него удобный редактор. А в идеале - конвертер, чтобы из npp прямо в png, типа как xmp (кстати, кроме гимпа, кто-нибудь может работать с этим форматом?)

А вы себе что присмотрели?

# Re: Настройки idec mobile
idec.talks
johnbrown(ping,9) — All
2020-09-25 06:10:46


Заметил довольно большой расход заряда - чуть больше 6% на дефолтных настройках.

# Битые текстуры на AMD Radeon Vega
linux.14
hugeping(ping,1) — All
2020-09-24 07:21:16


Купил в начале карантина два ноута: Acer Apire 3. И надо сказать, очень доволен (дёшево и эффективно). Но на ноуте частенько в 3d приложениях наблюдал битые текстуры. Не сказать, что критично, но -- напрягало. Быстрый поиск ничего не давал. Но в итоге, всё-таки нашлось:

# Переменная окружения
AMD_DEBUG=nodmacopyimage

По этой строчке проблема уже легко гуглится, так что можно за ней следить.

P.S. Следующие компы буду брать на AMD.

# Re: Вернуться в детство с PICO-8
std.hugeping
hugeping(ping,1) — boscholeg
2020-09-23 10:06:42


> Сейчас очередь за чем? Будет пико или инстед игрушка?

Хочется написать на метапарсере.

# Re: Вернуться в детство с PICO-8
std.hugeping
boscholeg(ping,5) — hugeping
2020-09-23 09:19:49


>> Спасибо за АА. Эта штука украла 2 часа моей жизни. Но, это были приятные два часы, полные взлетов и падений )

> Тогда вторую мою игру зацени: https://instead.itch.io/rr

>> Недавно открыл для себя фэнтези консоли. Пока присматриваюсь к TIC и ESP LGE. Битси уже в деле )

> Круто! TIC тоже смотрел. Решил чередовать: INSTEAD->PICO8->INSTEAD... ;)

Сейчас очередь за чем? Будет пико или инстед игрушка?

# Re: Вернуться в детство с PICO-8
std.hugeping
hugeping(ping,1) — johnbrown
2020-09-22 16:04:26


> Спасибо за АА. Эта штука украла 2 часа моей жизни. Но, это были приятные два часы, полные взлетов и падений )

Тогда вторую мою игру зацени: https://instead.itch.io/rr

> Недавно открыл для себя фэнтези консоли. Пока присматриваюсь к TIC и ESP LGE. Битси уже в деле )

Круто! TIC тоже смотрел. Решил чередовать: INSTEAD->PICO8->INSTEAD... ;)

# Re: Вернуться в детство с PICO-8
std.hugeping
johnbrown(ping,9) — Peter
2020-09-22 15:57:58


Спасибо за АА. Эта штука украла 2 часа моей жизни. Но, это были приятные два часы, полные взлетов и падений )

Недавно открыл для себя фэнтези консоли. Пока присматриваюсь к TIC и ESP LGE. Битси уже в деле )

# Re: Unicode строки в Instead
std.prog
hugeping(ping,1) — Frost
2020-09-22 15:00:55


> print(std.game.codepage)

Конечно, так не сработает, в этот момент game ещё нет. Но в моём коде std.game проверяется внутри функции, запуск которой предполагается в момент, когда игра уже запущена. Например, в start() и позже...

# Re: Unicode строки в Instead
std.prog
Frost(ping,10) — hugeping
2020-09-22 14:54:41


Файл с игрой называется main3.lua
P.S. Edited: 2020-09-22 14:59:01

Содержимое файла main3.lua

require 'sprite'
sprite.direct(true)
print(std.game.codepage)

# Re: Unicode строки в Instead
std.prog
hugeping(ping,1) — Frost
2020-09-22 14:36:39


> выяснилось, что std.game приводит к ошибке. Мне пришлось удалить фрагмент

Файл с игрой называется main3.lua или main.lua? Нужно, чтобы было main3.lua -- это новое INSTEAD API, старое API больше не поддерживается.

> Файл с кодом игры ведь обязан быть в кодировке UTF-8 (разве не так?). Зачем тогда эта проверка?

Формально, не обязан. Дело в том, что до сих пор есть поддержка разных кодировок, но по факту -- никто кроме utf-8 ничего не использует. И это хорошо.

# Re: Unicode строки в Instead
std.prog
Frost(ping,10) — hugeping
2020-09-22 14:17:47


Огромное спасибо за оперативную помощь! Мне ваши ответы действительно помогли. При анализе кода
local utf8 = (std.game.codepage == 'UTF-8' or std.game.codepage == 'utf-8')

выяснилось, что std.game приводит к ошибке. Мне пришлось удалить фрагмент

local utf8 = (std.game.codepage == 'UTF-8' or std.game.codepage == 'utf-8')
if not utf8 then return 1 end

Файл с кодом игры ведь обязан быть в кодировке UTF-8 (разве не так?). Зачем тогда эта проверка?

# Re: Unicode строки в Instead
std.prog
hugeping(ping,1) — Frost
2020-09-22 13:34:27


> Спасибо. Я благодарен за уделенное внимание моему вопросу. Однако на текущем этапе мне сложно разбираться в коде метапарсера.

Так там были готовые функции. Просто скопировать в свою игру.

local function utf_ff(b, pos)
	if type(b) ~= 'string' or b:len() == 0 then
		return 0
	end
	local utf8 = (std.game.codepage == 'UTF-8' or std.game.codepage == 'utf-8')
	if not utf8 then return 1 end
	local i = pos or 1
	local l = 0
	if b:byte(i) < 0x80 then
		return 1
	end
	i = i + 1
	l = l + 1
	while b:byte(i) and b:byte(i) >= 0x80 and b:byte(i) <= 0xbf do
		i = i + 1
		l = l + 1
		if i > b:len() then
			break
		end
	end
	return l
end

local function utf_chars(b)
	local i = 1
	local s
	local res = {}
	local ff = std.rawget(_G, 'utf8_next') or utf_ff
	while i <= b:len() do
		s = i
		i = i + ff(b, i)
		table.insert(res,  b:sub(s, i - 1))
	end
	return res
end

Вот это реализация utf_chars, которая сделает массив с литерами из строки:

local a = utf_chars("привет")

Мне просто неизвестно, какие функции нужны.

> Вытекающий вопрос: можно ли перевести Instead на работу с LUA версии 5.3, в которой есть встроенная поддержка Юникода?

ИНСТЕД и так работает (может быть собран) с Lua от 5.1 до 5.4. Но если нужно, чтобы игра работала на всех видах установок (не только на собственной версии), нужно пользоваться 5.1. В основном это связано с тем, что бинарные сборки используют LuaJit, который 5.1 (с расширениями).

# Re: Unicode строки в Instead
std.prog
Frost(ping,10) — Frost
2020-09-22 13:04:52


Спасибо. Я благодарен за уделенное внимание моему вопросу. Однако на текущем этапе мне сложно разбираться в коде метапарсера. Многое в ответе мне не ясно, например вы говорите, что "в последней версии INSTEAD есть и C реализация"; или "А вот как определяется, какую из реализаций брать - на Lua или на C. Чтобы работало и со старым и с новым INSTEAD". Это меня приводит в замешательство. Поэтому я продолжал искал ответ, который будет мне понятен на моем уровне изучения LUA. Кое что мне удалось найти. Ниже приведу несколько ссылок для тех, кто как и я имеет начальный уровень знаний.

Статья "Могу ли я использовать строки Юникода? Lua поддерживает Юникод?" http://lua-users.org/wiki/LuaUnicode" (на английском) в конце статьи даны ссылки на разные библиотеки для работы с Юникодом. Для себя я выделил две:

https://github.com/alexander-yakushev/awesompd/blob/master/utf8.lua самый простой вариант и

https://github.com/wikimedia/mediawiki-extensions-Scribunto/tree/master/includes/engines/LuaCommon/lualib/ustring имеет больший функционал
P.S. Edited: 2020-09-22 13:09:07

Вытекающий вопрос: можно ли перевести Instead на работу с LUA версии 5.3, в которой есть встроенная поддержка Юникода?

# Re: Малинка, как домашний веб сервер
pipe.2032
hugeping(ping,1) — boscholeg
2020-09-22 11:18:09


> Петр расскажи насколько равномерно корпус прогревается?
> Пробовал измерять температуру в разных частях корпуса?

Температуру смотрел только такими командами:

$ cat /sys/class/thermal/thermal_zone0/temp
$ vcgencmd measure_temp

На ощупь, верхняя часть нагрета равномерно.

> GUI и прочие десктопы ты на малинке поднял? Или работаешь через терминал?

Ничего, кроме ботов, ssh и ii-go не кручу там. Первый раз запускал графику, но потом сразу снёс. Возможно, буду экспериментировать с 9front, но не сейчас.

> Корпус мне такой тоже понравился хочу подобный заказать.

Да, правда мне по ошибке привезли корпус, в который можно ставить вентиляторы (идут в комплекте). Из-за этого, там не везде есть рёбра. Но, похоже, это не так уж и важно. Сейчас t == 39C :) Летом будет повыше, наверное.

# Re: Малинка, как домашний веб сервер
pipe.2032
boscholeg(ping,5) — hugeping
2020-09-22 10:35:30


Петр расскажи насколько равномерно корпус прогревается?
Пробовал измерять температуру в разных частях корпуса?
GUI и прочие десктопы ты на малинке поднял? Или работаешь через терминал?
P.S. Edited: 2020-09-22 10:35:42

Корпус мне такой тоже понравился хочу подобный заказать.

# Re: UTF8 строки в Instead
std.prog
hugeping(ping,1) — Frost
2020-09-21 19:03:05


> Приветствую, друзья. Подскажите пожалуйста как можно работать с кириллицей в Instead. Я имею ввиду функции len; sub и другие, работающие с однобайтовой кодировкой символов.

Привет!

На самом деле, в метапарсере есть такой код. Он написан на Lua. Но, в последней версии INSTEAD есть и C реализация, которая помогает этому Lua коду.

Наверное, проще всего посмотреть как это сделано в МП. Даю наводку: https://github.com/instead-hub/metaparser/blob/master/parser/mp.lua#L87

Функция, которая из строки делает массив литер.

Рядом есть более примитивные функции: utf_len, utf_char, utf_ff и utf_bb.

А вот как определяется, какую из реализаций брать -- на Lua или на C. Чтобы работало и со старым и с новым INSTEAD:

utf = {
    bb = std.rawget(_G, 'utf8_prev') or utf_bb;
    ff = std.rawget(_G, 'utf8_next') or utf_ff;
    len = std.rawget(_G, 'utf8_len') or utf_len;
    char = std.rawget(_G, 'utf8_char') or utf_char;
};

Прототипы функций если надо я могу вспомнить, но наверное есть смысл сначала посмотреть код, может быть там и так всё будет понятно. Навскидку:

utf_len, очевидно, возвращает число литер;
utf_char(строка, номер) - возвращает литеру по позиции;
utf_ff(строка, смещение) - возвращает смещение следующей литеры;
utf_bb(строка, смещение конца) - возвращает смещение предыдущей литеры;

# Unicode строки в Instead
std.prog
Frost(ping,10) — All
2020-09-21 15:14:58


Приветствую, друзья. Подскажите пожалуйста как можно работать с кириллицей в Instead. Я имею ввиду функции len; sub и другие, работающие с однобайтовой кодировкой символов. Имеет ли ядро движка встроенную поддержку и если да, то как получить доступ к UTF8 функциям. Если нет, подскажите наиболее оптимальную (проверенную) библиотеку для работы с юникодом. Заранее спасибо.
P.S. Edited: 2020-09-22 12:39:51 [изменено название]

# Re: Вернуться в детство с PICO-8
std.hugeping
hugeping(ping,1) — johnbrown
2020-09-20 13:39:58


Про bitsy знаю, иногда смотрю игры на нём. Правда это уже скорее специализированный движок. Да и только в вебе работающий.

Ещё есть такое понятие "flat games". Тоже любопытное явление. Можно на itch поискать. Артхаус как он есть.:)

# Re: Вернуться в детство с PICO-8
std.hugeping
johnbrown(ping,9) — Peter
2020-09-20 10:21:08


> TIC-80 классный. Но в PICO-8 подкупает минимализм, дальше которого уже просто некуда.

Есть bitsy. Он ещё меньше :)

На нем тоже много игр написано. Правда он больше под адвенчуры заточен. Игры на нем обычно очень небольшого размера 5-10 минут. Очень много достойных работ. https://itch.io/games/tag-bitsy

Например:

Деметра и Персефона
https://friendlycosmonaut.itch.io/demeterandpersephone

Diplomat simulator
https://wjhollyart.itch.io/diplomat-simulator

# Re: Малинка, как домашний веб сервер
pipe.2032
hugeping(ping,1) — johnbrown
2020-09-19 22:48:19


> Слабая, знаю, но надеялся, что греться хотя бы будет меньше.

Кстати, тоже думал о 3й. Боялся перегревов, а мощность мне не так уж и нужна. Но рискнул. 40C обычно температура, что очень неплохо. Правда, я корпус взял зверский-алюминевый. Как радиатор действует. Вообще, очень рад. Правда, народ пугает выходом из строя sd карт... Ну, посмотрим...

# Re: Обновления ii-go (движка узла ping)
ping.local
hugeping(ping,1) — johnbrown
2020-09-19 22:40:18


> Может стоит сделать редирект с syscall на https?

Я хочу, чтобы узел был доступен и через http. Хотя, наверное, можно сделать редирект только для syscall и не делать для http://hugeping.tk Но, кажется, это только все запутает.

# Re: Обновления ii-go (движка узла ping)
ping.local
johnbrown(ping,9) — hugeping
2020-09-19 19:59:50


hugeping> Теперь узел должен работать по https.

Может стоит сделать редирект с syscall на https?

# Re: Малинка, как домашний веб сервер
pipe.2032
johnbrown(ping,9) — hugeping
2020-09-19 19:15:19


Тоже купил малинку этой весной, когда началась вся эта заварушка с ковидлой. Raspbery 3 Model B. Слабая, знаю, но надеялся, что греться хотя бы будет меньше. До этого компа не было, смешно конечно, первое время выкручивался смартфоном, но задолбало... В итоге раскошелился ). Монитор от старого компьютера остался, клава - аналогично. Корпус взял от дискет (да, дискеты у меня тоже сохранились).
Серверный опыт ограничился настройкой бэкапов с телефона (termux) по ssh. Чисто для галочки - типа могу, но потом отказался в пользу usb: трафик, да и в сетевой безопасности я разбираюсь как коза в апельсинах. Там, конечно RSA ключи, и в настройках малины SSH можно отключить, но мне так проще. Сейчас вообще на бэкапы забил. Ну потеряется что-то, мы-то останемся )

Когда покупал малину брал с ней сд-карту. На ней была старая версия ос и она очень часто падала. Приходилось жёстко перезагружать девайс. Однажды не смог залогиниться. Короче, скачал последнюю версию. Сейчас все нормально работает, но я её нечасто включаю, но да бэкап нужен, неохота все заново настраивать.

+++ johnbrown

# luastatus
linux.14
Andrew Lobanov(tavern,1) — All
2020-09-19 18:25:07


Давно искал какую-нить генерилку статуса для i3 или dwm (я периодичечски "прыгаю" по wm да), чтобы можно было не только по времени, но и по событию обновлять строку статуса. Например, изменение громкости или переключение раскладки. Вот нашёл сабж. Очень простая штука, позволяющая достаточно гибко писать отображение информации на lua, перерисовывающая статус при его изменении, а не по таймеру. Поддерживает кучу всяких панелей, теоретически без особых проблем позволяет писать поддержку других панелей.

Есть в AUR, но там по умолчанию отключена сборка плагина для pulseaudio. Так что пришлось немного поправить PKGBUILD и теперь у меня очень симпатичный статус прямо в i3bar :)

Пробовал i3blocks, но он какой-то деревянный мне показался. Может, я просто не смог нормально с ним разобраться.

# Re: HP Ink Tank Wireless 410 series
linux.14
Andrew Lobanov(tavern,1) — vmg
2020-09-18 11:15:36


AL>> А что у тебя за система?
vmg> linux mint 18.3 (ubuntu 16.04 xenial)

Таки да. Я поэтому и ушёл со Slackware, что доступна только версия 14.2, вышедгая в 16-м году. На новом оборудовании у меня не заводится wifi-модуль, а более свежее ядро мне лень туда собирать :)

С одной стороны печально, что так случается, с другой -- новое оборудование требует нового кода. Мы живём в несовершенном мире :(

# Re: Пишу ноду ii/idec на go
idec.talks
Andrew Lobanov(tavern,1) — hugeping
2020-09-18 11:15:35


hugeping> Меня убедили начать комментировать код. :)

hugeping> Так что постепенно буду это делать. На данный момент описал функции в msg.go -- это базовые функции для манипуляции бандлами (decode/encode) и приём сообщений от поинтов.

Ну что я могу сказать? Хоть я и был среди убеждающих, ты подал хороший пример всем нам. Надо будет заняться документированием idec-client :)

# Re: Пишу ноду ii/idec на go
idec.talks
hugeping(ping,1) — Peter
2020-09-18 08:16:08


Меня убедили начать комментировать код. :)

Так что постепенно буду это делать. На данный момент описал функции в msg.go -- это базовые функции для манипуляции бандлами (decode/encode) и приём сообщений от поинтов.

https://github.com/gl00my/ii-go/blob/master/ii/msg.go

# Re: HP Ink Tank Wireless 410 series
linux.14
vmg(tavern,32) — Andrew Lobanov
2020-09-18 06:40:42


AL> А что у тебя за система?
linux mint 18.3 (ubuntu 16.04 xenial)

# Re: HP Ink Tank Wireless 410 series
linux.14
Andrew Lobanov(tavern,1) — vmg
2020-09-18 04:55:09


AL>> Повеяло историей про Столлмана и принтер :)
AL>> Хотя, тут всё не так плачевно, конечно.
vmg> Плачевно у меня со сканером canon lide 300. Попытался собрать sane backends, но оказалось, что система моя старая, и всё в ней старое. А тот sane, что в репозитории, не видит lide 300.

А что у тебя за система?

# Re: HP Ink Tank Wireless 410 series
linux.14
vmg(tavern,32) — Andrew Lobanov
2020-09-17 21:57:26


AL> Повеяло историей про Столлмана и принтер :)
AL> Хотя, тут всё не так плачевно, конечно.

Плачевно у меня со сканером canon lide 300. Попытался собрать sane backends, но оказалось, что система моя старая, и всё в ней старое. А тот sane, что в репозитории, не видит lide 300.
Разбираюсь покашто

# Re: HP Ink Tank Wireless 410 series
linux.14
Andrew Lobanov(tavern,1) — hugeping
2020-09-17 08:51:49


hugeping> P.S. Пишу это сообщение, так как после обновления пакета hplip потерял это изменение и разбирался повторно. :)

Повеяло историей про Столлмана и принтер :)

Хотя, тут всё не так плачевно, конечно.

# HP Ink Tank Wireless 410 series
linux.14
hugeping(ping,1) — All
2020-09-17 06:32:53


Купил тут МФУ. Специально брал с WiFi, чтобы можно было ставить куда угодно.

Поставил, подключил по USB, включил. Запускаю hp-wificonfig и... Пишет: нет поддерживаемых принтеров.

Ну, начал отлаживаться. К счастью, написано на питоне.

В общем, вот решение:

Файл: /usr/share/hplip/data/models
Ищем строку: model1=HP Ink Tank Wireless 410
После неё ищем wifi-config=0 и меняем строчку на wifi-config=3

Теперь hp-wificonfig увидит принтер и можно будет подключить его к домашней WIFI сети.

P.S. Пишу это сообщение, так как после обновления пакета hplip потерял это изменение и разбирался повторно. :)

# Ненастоящая победа open source
std.hugeping
hugeping(ping,1) — All
2020-09-16 19:25:59


Сегодня кажется, что open source победил окончательно и бесповоротно. Компании вкладываются в разработку ядра Linux, браузера chrome, компиляторов clang и многих других сложных проектов.

clang разрабатывается с целью замены gcc. chrome -- браузер, который постепенно вытесняет firefox. Docker, gitlab, VS Code -- можно долго перечислять успешные проекты, которые созданы коммерческими компаниями и развиваются как проекты с открытым исходным кодом.

Когда-то я тоже радовался chromium, clang и другим новым классным проектам. Я видел, что их качество действительно лучше, что старичок GNU всё возится с ворохом устаревших технологий, тщетно пытаясь догнать уходящий поезд прогресса. Да он же просто смешон!

Но потом я стал кое-что подозревать...

Да, есть целый пласт проектов, которые сложно создать в режиме "базара". Компьютерные игры, работа с графикой, CAD, офисные приложения... Как пример можно привести Photoshop и gimp. Или программы видеомонтажа. Чтобы удовлетворять стандартам рынка, такие программы сами должны создаваться участниками этого рынка. Но... Представьте себе, что все компании обанкротились. И что останется?

Что будет делать сообщество с многомиллионным кодом Chrome? Сможет ли оно его развивать? Сможет ли самоорганизоваться в сообщество, способное переварить этого монстра, который уже переплюнул по своей сложности ядро ОС? Сможет ли оно самостоятельно осознать и поддерживать такие проекты как: Clang, QT, VS Code?

Ок, VS Code кажется проектом попроще, не так ли? Но на чём написан VSCode? Сможет ли сообщество сохранить инфраструктуру, которая нужна для функцилнирования такого "простого" на вид VSCode?

Открытый исходный код сам по себе не означает, что вы им владеете. Если никто не понимает код, или мера сложности проекта такова, что для его поддержки и развития нужна жёстко организованная корпоративная вертикаль и деньги, вы не владеете проектом.

Проект, который способен жить только с помощью вливаний денег корпораций -- противоречит духу свободы, и тип выбранной лицензии здесь второстепенный вопрос.

И здесь я снова смотрю на GNU, которая берёт на себя то, что может поднять. Да, gimp это не фотошоп. Но этот проект принадлежит нам! Да, clang, возможно современней GCC. Но GCC принадлежит нам!

Я пишу эти строки в браузере NetSurf и понимаю, что этот браузер свободен. Да, он не удовлетворяет коммерческим стандартам, но он достаточно прост, чтобы развиваться в режиме "свободного творчества".

Раньше, чтобы написать новую ОС, нужно было решить основную проблему -- поддержку оборудования. Сегодня такой краеугольной проблемой является... возможность работы современного браузера! Для проектов типа 9front http://9front.org -- это нереализуемо, если говорить о Firefox или Chrome. Но вот заставить работать NetSurf - вполне по силам одному программисту, работающему над проектом по вечерам.

И тут я задаю неудобный вопрос. А Linux-то, linux ещё наш? Или он уже стал товаром, которым торгуют корпорации?

# Блокировка Yandex рекламы
std.favorites
hugeping(ping,1) — hugeping
2020-09-15 10:21:56

# Лайфхаки
std.favorites
hugeping(ping,1) — All
2020-09-15 10:21:09


Сюда планирую собирать решения каких-то технических проблем (в основном, Linux/Unix).

# Emacs 27.1: проблема с кодировкой в gnus
linux.14
hugeping(ping,1) — All
2020-09-15 08:10:09


Решил написать сюда, чтобы не потерять.

Несколько лет пользуюсь gnus. И тут, после последнего обновления emacs, часть писем у меня стала отображаться в битой кодировке. В теле письма всё ок, стоит utf-8.

Я уже не помню, как именно удалось локализовать проблему (скорее всего просто трейсил и менял куски gnus на старый gnus из 26 emacs), но вот "волшебная строчка", которая помогла:

(setq nnheader-file-coding-system 'raw-text)

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — hugeping
2020-09-14 22:14:25


Пофиксил, фетчу тебя :)

# Re: Что с станцией lessmore?
idec.talks
hugeping(ping,1) — Difrex
2020-09-14 21:34:38


Сделал исправление тоже, поставил на тебя фетч (blog.difrex). Ожидаю взаимного фетча. ;)

# Автоматический тайлинг в Sway
difrex.blog
Difrex(tavern,23) — All
2019-04-07 15:08:45


Я давно использую i3wm в работе, а после выхода версии 1.0 Sway я перешел на него с i3. Sway - это пракатически полностью совместимый с i3 композитор Wayland. По-этому перейти на него оказалось очень просто. Мои конфиги Sway можно посмотреть на Github.

Почему-то я долгое время думал, что мне в i3/sway не хватает полностью ручного тайлинга, я пробовал различные оконные менеджеры с ручным тайлингом, такие как, `bspwm`, `herbstlutfwm` и другие, но они не заходили. Потом я решил попробовать AwesomeWM, все-таки это по сути фреймворк и на Lua можно написать все, что угодно. В нем мне очень понравилась стандартная возможность автоматического тайлинга. Вот, что мне переодически нужно, подумал я. Но во всех WM, что я пробовал не было нормальной поддержки скретчпадов - это такие плавающие окна, которые большую часть времени скрыты, и показать их можно, например по комбинации клавишь. Что же мне на самом деле хотелось от WM - скретчпады, полуручной и автоматический тайлинг, возможность менять поведение скриптами на любом языке. По всем параметрам подходил Sway за исключением автоматического тайлинга. Было решено добавить его самостоятельно.

После небольшого иследования этого вопроса оказалось, что у sway есть IPC с возможностью подписки на определенные события. Проблема возникла в том, что существующие биндинги к i3 ipc не подходили, т.к. формат дерева в JSON у Sway отличается, а так же добавляются новые возможности, типа, получения устройств ввода, чего не было в i3.

Так я решил написать(и написал) биндинг к Sway IPC на Go. И уже поверх этого начал писать демона, который реализует автоматический тайлинг.

На данный момент я реализовал `spiral` layout, который работает, так как я хочу и полностью меня устраивает. Так же на начальном этапе реализован `left` layout. Демонстрацию этих режимов можно посмотреть в видео ниже.

## Как этим воспользоваться?

Для начала нужно скомпилировать swaymgr. Из зависимостей только Go - поставь его из репозиториев твоего дистрибутива.


git clone https://github.com/Difrex/gosway
cd gosway/swaymgr
go get -t -v ./...
go build -o ~/.local/bin/swaymgr


Теперь можно добавить swaymgr в конфигурацию sway. Добавь следующие строчки в `~/.config/sway/config`


exec_always ~/.local/bin/swaymgr
bindsym $mod+Alt+m exec ~/.local/bin/swaymgr -s 'set manual'
bindsym $mod+Alt+l exec ~/.local/bin/swaymgr -s 'set left'
bindsym $mod+Alt+s exec ~/.local/bin/swaymgr -s 'set spiral'


Комбинации клавишь меняй по своему вкусу.

Swaymgr запоминает свою расскладку для каждого рабочего стола, а состояние хранит в `~/.autotiling.bolt`. В репозитории ты так же найдешь скрипт, который можно использовать, например, с `i3blocks`.

## Про внутреннее устройство

Если вдруг тебе захочется помочь в разработке, то вот небольшой гайд по тому, как правильно это сделать.

Swaymgr - это отлельное приложение, которое использует `gosway/ipc`.

Для того, чтобы взаимодействовать со Sway через unix-socket необходимо два подключения:

1. Соединение для передачи различных комманд
2. Соединение на которое будут приниматься события от оконного менеджера

Так же для хранения настроек рабочих столов используется встроенная, минималистичная база данных Bolt. Функция `newManager() (*manager, error)` создает все необходимые подключения и вызывает функцию инициализации интерфейсов `Layout`. Возвращаемая структура имеет такой вид:


type manager struct {
commandConn *ipc.SwayConnection
listenerConn *ipc.SwayConnection
store *store
layouts map[string]Layout
}


Главный интерфейс, с помощью которого реализуются все режимы - Layout, выглядит он так: Файл `swaymgr/layouts.go`


type Layout interface {
// PlaceWindow must receive an *ipc.Event
// and do the container manipulation
PlaceWindow(*ipc.Event) error
// Manage must store WorkspaceConfig in the database with
// the workspace name, layout name and with the Managed: true
Manage() error
}


У этого интерфейса есть всего два метода:

* `Manage() error` - вызывается тогда, когда текущий рабочий стол переключается в какой-либо режим
* `PlaceWindow(*ipc.Event) error` - вызывается тогда, когда создается новый контейнер на рабочем столе, который является управляемым.

### Как работает spiral layout

Я рассмотрю управлене окнами на примере реализации режима spiral.

Структура этого режима состоит всего из двух полей:

* `Conn *ipc.SwayConnection` - Коммандное подключение к unix-сокету Sway
* `store *store` - Открытое соединение к базе данных, в котой хранятся текущие настройки рабочих столов

При наступлении события создания нового окна, и если текущий рабочий стол управляется, данное событие передается в метод `PlaceWindow(event *ipc.Event)`. Для начала необходимо найти текущее окно на котором находится фокус:


nodes, err := s.Conn.GetFocusedWorkspaceWindows()
if err != nil {
return err
}
var result ipc.Node
for _, node := range nodes {
if node.Focused {
result = node
break
}
}


Далее вся логика позиционированния окон помещается в 7 строчек:


if result.WindowRect.Width > result.WindowRect.Height {
_, err := s.Conn.RunSwayCommand(fmt.Sprintf("[con_id=%d] split h", event.Container.ID))
return err
} else {
_, err := s.Conn.RunSwayCommand(fmt.Sprintf("[con_id=%d] split v", event.Container.ID))
return err
}


Если у окна с фокусом длина больше ширины, то новый контейнер разделяем по горизонтали, иначе по вертикали. Все. Это работает замечательно и эту логику работы менять я не буду.

## Зарезервированные режимы

Я заранее зарезервировал некоторые режимы которые очень хочется реализовать. Вот они:

* `type FiberLayout struct{}` - режим подсмотренный в AwesomeWM. Окна размещаются симметрично друг под другом и вдоль
* `type TopLayout struct{}` - самое большое окно размещается вверху экрана, остальные внизу разделяясь по горизонтали
* `type BottomLayout struct{}` - тоже самое, что и для TopLayout, но главное окно находится внизу
* `type RightLayout struct{}` - тоже самое, что и LeftLayout, но главное окно размещается справа

Проект на Github. Учитывай, что это пока самая ранняя реализация и тут могут быть баги в больших колличествах, правда ничего критичного я пока не находил - пользоваться можно. Буду очень рад баг-репортам и фич-реквестам, а так же особенно пулл-реквестам. Лицензия проекта: Apache.

Ссылка: https://difrex.lessmore.pw/post/sway-autotiling/

# Ограничиваем в правах Firefox с помощью apparmor
difrex.blog
Difrex(tavern,23) — All
2018-11-27 09:45:36


> AppArmor — программный инструмент упреждающей защиты, основанный на политиках безопасности, которые определяют, к каким системным ресурсам и с какими привилегиями может получить доступ то или иное приложение. В AppArmor включён набор стандартных профилей, а также инструменты статического анализа и инструменты, основанные на обучении, позволяющие ускорить и упростить построение новых профилей.

© Wikipedia.org

Самое опасное приложение на десктопе, как я считаю, - это браузер. На меня напал очередной приступ паранои и я написал профиль apparmor для Firefox.

## tl;dr

Ставим утилиты:


pacman -S apparmor audit


Apparmor входит в ядро, так что нужно только его включить передав соответствующие параметры в cmdline Linux. Правим /etc/default/grub:


GRUB_CMDLINE_LINUX="apparmor=1 security=apparmor audit=1"


Включаем сервисы:


systemctl enable apparmor
systemctl enable auditd


Разрешаем себе читать audit.log


groupadd -r audit
gpasswd -a USERNAME audit


В /etc/audit/auditd.conf прописываем только что созданную группу: `log_group = audit`

Перезагружаемся

Проверяем статус apparmor:


apparmor_status
apparmor module is loaded.
62 profiles are loaded.
49 profiles are in enforce mode.
...
SKIP
...


Пишем профиль /etc/apparmor.d/usr.bin.firefox


#include <tunables/global>

/usr/bin/firefox {
#include <abstractions/base>
#include <abstractions/bash>

# Даем доступ к видео, памяти и tty
/dev/dri/** wr,
/dev/dri/ r,
/dev/shm/ r,
/dev/tty* rw,
/dev/shm/* rw,

# Даем доступ к конфигам, а так же сети и SSL
/etc/fonts/** r,
/etc/drirc r,
/etc/mime.types r,
/etc/pulse/client.conf r,
/etc/nsswitch.conf r,
/etc/ca-certificates/** r,
/etc/resolv.conf r,
/etc/host.conf r,
/etc/ssl/openssl.cnf r,
/etc/hosts r,
/etc/gai.conf r,
/etc/machine-id r,

# Разрешаем исполнение самого себя
# /usr/bin/bash ix,
/usr/bin/firefox rix,
/usr/bin/chrome-gnome-shell rix,
# Разрешаем грепать
/bin/grep ixr,

# Доступ к библиотека на чтение/подключение
/usr/lib/* rm,
/usr/lib/dri/* rm,
/usr/lib/python3.7/** rm,
/usr/lib/firefox/** rixm,

# Доступ к системным FS
/sys/devices/system/cpu/present r,
/proc/** r,
/sys/devices/** r,

/usr/share/hunspell/ r,
/usr/share/fonts/** rwkl,
/usr/share/sounds/** r,
# тут 1000 нужно заменить на id своего юзера
/run/user/1000/** r,

# Разрешаем писать во временную директорию
/tmp/** rwk,

# Даем права на чтение/запись/лок/линкинг
/run/user/1000/** rwkl,
# Разрешаем писать в сокет dbus
/var/run/dbus/system_bus_socket w,

# Шрифты/значки и.т.д
/var/cache/fontconfig/** r,
/var/lib/flatpak/exports/** r,
/usr/share/fonts/ r,
/usr/share/icons/** r,
/usr/share/glib-2.0/** r,
/usr/lib/firefox/** rwkix,
/usr/share/ca-certificates/** r,
/usr/lib/gtk-3.0/** rmk,
/usr/share/applications/kde4/ r,
/usr/share/pixmaps/ r,
/usr/share/icons/ r,
/usr/share/libthai/thbrk.tri r,
/usr/local/share/applications/ r,
/usr/local/share/applications/* r,
/usr/local/share/mime/mime.cache r,
/usr/share/applications/ r,
/usr/share/applications/* r,
/usr/share/gdm/applications/ r,
/usr/share/gdm/applications/* r,
/usr/share/locale-langpack/** r,
/usr/share/gtk-3.0/** r,
/usr/share/mime/** r,
/usr/share/myspell/** r,
/usr/share/themes/** r,

# Назначаем Firefox влядельцем ~/.mozilla и даем ему там все права
# кроме исполнения и подключения библиотек
owner @{HOME}/.mozilla/** rwkl,
@{HOME}/.cache/fontconfig/** r,
@{HOME}/.cache/mozilla/** rwk,
@{HOME}/.cache/thumbnails/** r,
@{HOME}/.config/dconf/* rkw,
@{HOME}/.fonts/ r,
@{HOME}/.local/share/icons/** r,
@{HOME}/.cache/mesa_shader_cache/index rwk,
@{HOME}/.local/lib/python3.7/** rm,
@{HOME}/.config/fcitx/dbus/* r,
@{HOME}/.local/share/recently-used.xbel rk,

# Определяем каталоги в домашней директории куда можно ходить
# Firefox и с какими правами.
# В моем случае браузер не может даже получить список
# каталогов, но может читать в разрешенных местах и писать в ~/Загрузки
@{HOME}/Изображения/ r,
@{HOME}/Документы/ r,
@{HOME}/Загрузки/ r,
@{HOME}/Видео/ r,
@{HOME}/Музыка/ r,
@{HOME}/soft/ r,
@{HOME}/Изображения/** r,
@{HOME}/Документы/** r,
@{HOME}/Музыка/** r,
@{HOME}/Загрузки/** rwk,
@{HOME}/Видео/** r,
@{HOME}/soft/** r,

# Кэши и локальные конфиги
@{HOME}/.local/share/fonts/ r,
@{HOME}/.fonts/** r,
@{HOME}/.ICEauthority r,
@{HOME}/.Xauthority r,
@{HOME}/.adobe/**/ r,
@{HOME}/.config/* r,
@{HOME}/.cache/* wrk,
@{HOME}/.config/gtk-2.0/* r,
@{HOME}/.config/gtk-3.0/* r,
@{HOME}/.fonts.conf r,
@{HOME}/.icons/ r,
@{HOME}/.local/share/applications/ r,
@{HOME}/.local/share/applications/* r,
@{HOME}/.local/share/fonts/** r,
@{HOME}/.local/share/icons/ r,
@{HOME}/.local/share/mime/mime.cache r,
@{HOME}/.pulse-cookie krw,
@{HOME}/.config/pulse/** krw,
}


PULL THE LEVER


aa-enforce /etc/apparmor.d/usr.bin.firefox
Назначение /etc/apparmor.d/usr.bin.firefox принудительного режима.


Теперь можно запустить браузер и проверить его работоспособность. Наблюдаем через `tail -f /var/log/audit/audit.log | grep DENIED` что было запрещенно Firefox.

Для меня, например, это:


type=AVC msg=audit(1543307263.804:81037): apparmor="DENIED" operation="open" profile="/usr/bin/firefox" name="/etc/passwd" pid=31159 comm="firefox" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
type=AVC msg=audit(1543307263.884:81039): apparmor="DENIED" operation="exec" profile="/usr/bin/firefox" name="/usr/bin/lsb_release" pid=31177 comm="firefox" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0
type=AVC msg=audit(1543307263.991:81040): apparmor="DENIED" operation="open" profile="/usr/bin/firefox" name="/dev/" pid=31156 comm="firefox" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
type=AVC msg=audit(1543307266.698:81043): apparmor="DENIED" operation="open" profile="/usr/bin/firefox" name="/usr/bin/" pid=31493 comm="chrome-gnome-sh" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
type=AVC msg=audit(1543307266.944:81044): apparmor="DENIED" operation="exec" profile="/usr/bin/firefox" name="/usr/bin/ldconfig" pid=31533 comm="chrome-gnome-sh" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0
type=AVC msg=audit(1543307266.968:81045): apparmor="DENIED" operation="exec" profile="/usr/bin/firefox" name="/usr/bin/gcc" pid=31534 comm="chrome-gnome-sh" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0


Зачем браузеру запускать компилятор я категорически не понимаю.

Смотрим еще раз в `apparmor_status`, в конце должно быть что-то подобное:


...
9 processes are in enforce mode.
/usr/lib/firefox/firefox (587) /usr/bin/firefox
/usr/lib/firefox/firefox (3857) /usr/bin/firefox
/usr/lib/firefox/firefox (31156) /usr/bin/firefox
/usr/lib/firefox/firefox (31212) /usr/bin/firefox
/usr/lib/firefox/firefox (31298) /usr/bin/firefox
/usr/bin/python3.7 (31491) /usr/bin/firefox
/usr/lib/firefox/firefox (31516) /usr/bin/firefox
/usr/bin/ntpd (1462) /usr/{bin,sbin}/{,open}ntpd
/usr/bin/dnsmasq (1510) dnsmasq


Все довольно просто в отличии от того же SELinux. А еще у apparmor есть очень хорошая документация с quick guide.

Ссылка: https://difrex.lessmore.pw/post/apparmor-firefox/

# Читаем почту в GNU Emacs
difrex.blog
Difrex(tavern,23) — All
2018-08-21 14:00:20


И так по обсуждению из вот этого вот треда(стартовый пост) у меня получилось настроить Gnus для работы с пятью почтовыми аккаунтами и отказаться от Evolution.

На самом деле связка получилась такая: fetchmail забирает письма, раз в 5 минут и запускает procmail для фильтрации сообщений, procmail сохраняет сообщения в $MAILDIR, дальше уже Gnus читает почту и показывает ее. Чтобы иметь нормальные уведомления я использую индексер почты mu, i3blocks запускает раз в 30 секунд скрипт проверки на новые письма и отправляет уведовления через libnotify, ну и иконку на панели рисует.

Вот так примерно это выглядит в ASCII-арте:


+-----------+ +------------+ +------------+ +------------+
| fetchmail | |procmail | |Maildir | |Gnus |
| +-----+filters +----+ +----+ |
+----+------+ +------------+ +-----+------+ +------+-----+
| | |
| | |
| | |
| +--------------+ +-----+------+ +-----+-----+
| |i3blocks | |mu indexer | |BBDB |
| |libnotify +----------+ | |contacts |
| +--------------+ +-----+------+ +-----------+
| |
| |
| +-----+------+
+------------------------------+systemd user|
|and timers |
+------------+


> Такие cхемки, кстати, очень удобно рисовать в artist-mode

Я настраивал все на Arch Linux, но на самом деле это все заработает в любом GNU Linux.

## Ставим пакеты

Ставим пакеты:


sudo pacman -S mu fetchmail procmail


Ставим BBDB в Emacs


M-x package-install RET bbdb RET
M-x package-install RET all-the-icons-gnus RET


BBDB нам нужен для автодополнения контактов в поле To. Да и вообще это хорошая быстрая база контактов для Emacs. А вот пакет all-the-icons-gnus рисует красивые иконки :).

## Правим конфиги

### fetchmail

Для начала нам необходимо настроить fetchmail, который будет забирать почту по IMAP/POP.

Редактируем ~/.fetchmailrc:


set daemon 300 # fetch mail every 5 minutes
set logfile ~/Mail/fetchmail.log # Logfile

poll imap.gmail.com with proto IMAP
user 'YOU_USER' there with password 'YOU_PASSWORD'
options ssl keep
mda 'procmail -d %T'


Подобным образом определяем все свои аккаунты.

Чтобы не использовать пароли в открытом виде можно наложить патч на fetchmail.

### procmail

Для фильтрации почты и расскидывания ее по каталогам будем использовать procmail - у него отличная гибкая система фильтров на регекспах.

Редактируем ~/.procmailrc:


MAILDIR=$HOME/Mail # You'd better make sure it exists

DEFAULT=$MAILDIR/mbox/
LOGFILE=$MAILDIR/log
LOCKFILE=$HOME/.lockmail

:0 # socials
* ^From.*@.*(twitter|vk\.com|facebook|golos\.io)
social/

:0 # JIRA
* .*Subject.*(\[JIRA\]|\[WGJIRA\]).*
jira/

:0 # Gitlab
* ^From.*gitlab@gitlab.*
Gitlab/


Свои фильтры пишем дальше аналогично - тут все просто. Да, и убедитесь, что каталог `$MAILDIR` существует.

### msmtp

msmtp эта штука, которая позволяет отправлять письма через нужный сервер smtp. Определяет аккаунт она по полю From.

Редактируем ~/.msmtprc:


defaults
auth on
tls on
logfile ~/.msmtp.log
tls_certcheck on
tls_trust_file /etc/ssl/cert.pem

account difrex
host smtp.googlemail.com
port 587
from my.mail@gmail.com
user USERNAME
password PASSWORD


Аналогично для остальных аккаунтов.

### Systemd

Теперь необходимо написать нужные юниты и таймеры. Юнит для fetchmail будет выглядеть так:

~/.config/systemd/system/fetchmail.service


[Unit]
Description=Fetchmail
After=network-online.target

[Service]
Type=forking
ExecStart=/usr/bin/fetchmail

[Install]
WantedBy=default.target


Включаем и запускаем его:


systemctl --user enable fetchmail.service
systemctl --user start fetchmail.service


Теперь fetchmail будет стартовать после успешного логина в систему.

Настроим индексацию почты в mu:

~/.config/systemd/user/mu.timer


[Unit]
Description=mu mail indexer timer
Documentation=man:mu(1)

[Timer]
OnCalendar=*:0/5

[Install]
WantedBy=timers.target



И сервис

~/.config/systemd/system/mu.service


[Unit]
Description=mu email indexer
After=fetchmail.service

[Service]
Type=oneshot
ExecStart=/usr/bin/mu index
Environment=MAILDIR=/home/difrex/Mail # тут нужно указать свой MAILDIR


Включаем и стартуем


systemctl --user enable mu.timer
systemctl --user start my.timer


### i3blocks

Настроим вывод значка с колличеством непрочтенных писем в i3bar и отправку уведомлений. Для этого напишем простой скрипт на bash.

~/.config/i3/mail.sh


#!/bin/bash

MAILDIR=/home/difrex/Mail; export MAILDIR # тут нужно указать свой MAILDIR
COUNT="$(/usr/bin/mu find date:15m..now and flag:unread 2>/dev/null | wc -l)"

# Write notify lock
write_notify_lock() {
mkdir -p ~/.cache
echo $COUNT > ~/.cache/.mail_notify_lock
}

# Cleanup lock
clean_notify_lock() {
rm -f ~/.cache/.mail_notify_lock
}

if [[ $COUNT -gt 0 ]]; then
if [[ ! -f ~/.cache/.mail_notify_lock ]] || [[ $COUNT -gt $(/usr/bin/cat ~/.cache/.mail_notify_lock) ]]; then
write_notify_lock
/usr/bin/notify-send 'New mail' "$(/usr/bin/mu find date:15m..now and flag:unread 2>/dev/null | tail -1)"
fi
else
if [[ -f ~/.cache/.mail_notify_lock ]]; then
clean_notify_lock
fi
fi

echo $COUNT


> Не забываем сделать скрипт исполняемым

И в конфиг i3blocks.conf нужно добать секцию с нашим скриптом:


[mail]
label=
interval=30
command=~/.config/i3/mail.sh


Выглядит иконка в баре вот так:

А уведомление в dunst так:

## Gnus

Переходим к самому интересному, а именно к настройке Gnus.

Редактируем файл ~/.gnus.el.


;;; .gnus.el --- GNUs configuration
;;; Commentary:
;;; Code:

(require 'all-the-icons-gnus) ;; Наводим красоту
(all-the-icons-gnus-setup)

(setq user-mail-address "my_email@example.com") ;; Будет по-умолчанию в поле From
(setq user-full-name "Denis Zheleztsov") ;; Устанавливаем, как нас зовут

;; Показываем, что нужно смотреть в MAILDIR
(setq gnus-select-method
'(nnmaildir "mail" (directory "~/Mail"))
mail-sources '((maildir :path "~/Mail" :subdirs ("cur" "new")))
mail-source-delete-incoming nil)

;; arbitrary name after "nnmaildir+"
(setq gnus-message-archive-group "nnmaildir+mail:outbox")
(setq message-sendmail-envelope-from 'header)
(setq mail-envelope-from 'header)
(setq message-send-mail-function 'message-send-mail-with-sendmail)

;; Устанавливаем в качестве программы для отправки писем msmtp
(setq sendmail-program "/usr/bin/msmtp")
(setq message-sendmail-envelope-from 'header)

;; Сортируем письма по дате
(setq gnus-thread-sort-functions '(gnus-thread-sort-by-most-recent-date))

;; Добавляем автодополнение по TAB для поля To
(add-hook 'message-mode-hook
(function (lambda()
(local-set-key (kbd "<tab>") 'bbdb-complete-mail))))

;; Если адресса получателя нет в базе BBDB - добавляем
(add-hook 'message-setup-hook 'bbdb-mail-aliases)

;; Добавляем в базу контактов адресатов из входящей почты
(bbdb-initialize 'gnus 'message)
(bbdb-mua-auto-update-init 'gnus)
(setq bbdb-mua-auto-update-p 'create)

;; Говорим демону Gnus проверять новую почту каждые пять минут
(gnus-demon-add-handler 'gnus-demon-scan-news 5 t)
(gnus-demon-init)

;;; .gnus.el ends here


Все! Нажимаем `M-x RET gnus RET` и радуемся.

Так выглядит буфер с группами и непрочитанными сообщениями:

А так список сабжей в группе(синим цветом показаны прочитанные сообщения):

> Обновлять групповой буфер можно по g, а написать новое сообщение по m. Отправить набраное сообщение через C-c C-c. Ответ на сообщение с цитатой R, без - r.

Ссылка: https://difrex.lessmore.pw/post/gnus-multi-accounts/

# Автодополнение для python с LSP в GNU Emacs
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 15:40:10


The Language Server Protocol (LSP) - это открытый, основанный на JSON-RPC протокол для использования между редакторами исходного кода и серверами, которые предоставляют специфические для языка программирования функции. Цель протокола заключается в том, чтобы обеспечить поддержку автодополнения языка программирования независимо от любого редактора или среды IDE.

LSP дает реально крутые штуки, такие как:

* Показ документации для модуля под курсором

* Автодополнение по точке. На самом деле это `company-lsp`, но про это будет дальше.

* Интеграция с flycheck

И еще кучу всего на самом деле. Все возможные настройки можно будет увидеть по `M-x customize RET lsp RET`.

## Конфигурация

Для начала нужно установить сам language server для python. Для Arch/Manjaro установка будет выглядеть так:


sudo pacman -S python-language-server


С системными зависимостями разобрались. Приступаем к `init.el`. Будем использовать `use-package`, потому что не использовать его - это отстой. Но каждый решает сам.

Включаем `lsp-mode`. Да, для lsp нужно что-то, чем определить корневой каталог для проекта. Я использую везде projectile.


;; LSP settings
(use-package lsp-mode
:ensure t
:config
;; make sure we have lsp-imenu everywhere we have LSP
(require 'lsp-imenu)
(add-hook 'lsp-after-open-hook 'lsp-enable-imenu)
;; get lsp-python-enable defined
;; NB: use either projectile-project-root or ffip-get-project-root-directory
;; or any other function that can be used to find the root directory of a project
(lsp-define-stdio-client lsp-python "python"
#'projectile-project-root
'("pyls"))

;; make sure this is activated when python-mode is activated
;; lsp-python-enable is created by macro above
(add-hook 'python-mode-hook 'lsp-python-enable)

;; lsp extras
(use-package lsp-ui
:ensure t
:config
(setq lsp-ui-sideline-ignore-duplicate t)
(add-hook 'lsp-mode-hook 'lsp-ui-mode))

(use-package company-lsp
:config
(push 'company-lsp company-backends))

;; NB: only required if you prefer flake8 instead of the default
;; send pyls config via lsp-after-initialize-hook -- harmless for
;; other servers due to pyls key, but would prefer only sending this
;; when pyls gets initialised (:initialize function in
;; lsp-define-stdio-client is invoked too early (before server
;; start)) -- cpbotha
(defun lsp-set-cfg ()
(let ((lsp-cfg `(:pyls (:configurationSources ("flake8")))))
;; TODO: check lsp--cur-workspace here to decide per server / project
(lsp--set-configuration lsp-cfg)))
(add-hook 'lsp-after-initialize-hook 'lsp-set-cfg))


flake8, autopep8, fci, anaconda, rainbow-delimiters(я их везде юзаю):


;; Python mode hook
(defun my-python-mode-hook ()
"Define hook."

(use-package flymake-python-pyflakes
:config
(setq flymake-python-pyflakes-executable "flake8")
(setq flymake-python-pyflakes-extra-arguments '("--max-line-length=99"))
(flymake-python-pyflakes-load))

(use-package py-autopep8
:config
(setq py-autopep8-options '("--max-line-length=99"))
(py-autopep8-enable-on-save))

;; Enable rainbow
(use-package rainbow-delimiters)
(rainbow-delimiters-mode-enable)

(use-package highlight-indent-guides)
(use-package company)
(use-package anaconda-mode)
(use-package company-anaconda
:config
(add-to-list 'company-backends '(company-anaconda :with company-capf)))

(use-package flycheck-pyflakes
:config
(setq flychek-flake8-maximum-line-lenght 99))

(setq-default py-shell-name "ipython")
(setq-default py-which-bufname "IPython")
;; Fill column indicator
(use-package fill-column-indicator
:init
:config
(setq-default fill-column 99)
(setq fci-rule-width 1)
(setq fci-rule-color "#696969"))

(fci-mode)

(anaconda-mode +1)
(anaconda-eldoc-mode)
(highlight-symbol-mode +1)
(highlight-indent-guides-mode)
(company-mode))

(use-package python
:mode ("\\.py\\'" . python-mode)
:interpreter ("python" . python-mode)
:init
(add-hook 'python-mode-hook 'my-python-mode-hook))


Все!

Спасибо вот этому чуваку.

Ссылка: https://difrex.lessmore.pw/post/python-lsp/

# Рига
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:49


Съездили тут на днях погулять в Латвию. Сели в машину и поехали. Границу пересекали в Бемякони, туда(к литовцам) въехали за два часа - нормалек.

Периодически шел дождь, но в целом погода была ничего.

## Рига

От границы до Риги дорога заняла часа 4-5. Старый город порадовал, красив.

Заехали на море(Рижский залив точнее). Пустынный солнечный пляж - это прикольно, но ледяной ветер не давал вдоволь насладиться видом и пробыли мы там всего минут 30.

Помимо Риги заезжали еще в несколько мест.

## Цесис

## Бауска

## Тракай

## Дорога обратно

По дороге обратно дождь чередовался с солнцем и было красиво.

Границу пересекли вечером за 3 часа. В Минск приехали уже в час ночи.

Ссылка: https://difrex.lessmore.pw/post/riga/

# Минск 08.05.2017
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:49


Фотки без обработки, тупо RawTherapee -> export.

## Верхний город

## Центр

## Площадь независимости

Ссылка: https://difrex.lessmore.pw/post/minsk-08-05-17/

# Пилим i3wm
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:49


Я тут на ЛОРе недавно постил скриншот и, вроде, людям понравилось. Попробую разобрать тут свой конфиг.

## Софт

Я использую Ubuntu 16.04, так что все действия актуальны для нее.

* i3-gaps

Это форк оригинального i3, где добавляются гапсы(отступы между окнами).

Сборку и установку производим так:


git clone https://github.com/Airblader/i3 -b 4.13
cd i3
dpkg-checkbuilddeps # проверяем какие зависимости нужно установить для сборки пакета, устанавливаем их.
dpkg-buildpackage -uc -us # собираем пакет
sudo dpkg -i ../i3-wm_4.13-1_amd64.deb # устанавливаем


* i3lock

Это блокировщик экрана. Ставим его из репозитория universe.

* compton

Тени, прозрачности и прочая красота. Так же ставим из официальных репозиториев.

* polybar

Панель, которую я использую в качестве замены стандартного i3bar.

Компиляем


git clone --branch 3.0.5 --recursive https://github.com/jaagr/polybar
mkdir polybar/build
cd polybar/build
cmake ..
make install


* rofi

Лаунчер. Так же ставим из репозиториев.

* feh

На самом деле - это просмотрщик изображений, но еще он позволяет установить обои.

* dunst

Уведомления(libnotify) рабочего стола.

## Конфигурация

Можно приступать к настройке WM.

~/.config/i3/config


# Клавиша super в качестве модификатора
set $mod Mod4
# Шрифты
font pango:hack 12
# Alt в качестве модификатора для управления плавающими окнами
floating_modifier Mod1
# Терминал
bindsym $mod+Return exec i3-sensible-terminal
# Закрытие окна
bindsym $mod+q kill

# Запуск лаунчера
bindsym $mod+d exec rofi -show run


Для настройки цветов лаунчера в ~/.Xresources пишем:


! ------------------------------------------------------------------------------
! ROFI Color theme
! ------------------------------------------------------------------------------
rofi.color-enabled: true
rofi.color-window: #393939, #393939, #268bd2
rofi.color-normal: #393939, #ffffff, #393939, #268bd2, #ffffff
rofi.color-active: #393939, #268bd2, #393939, #268bd2, #205171
rofi.color-urgent: #393939, #f3843d, #393939, #268bd2, #ffc39c


Hint: На сайте rofi можно найти несколько тем.

Локсрин. Я не использую комбинацию $mod+jklh для переключения между окнами, мне хватает стрелочек. Биндим i3lock на $mod+l.


# Lock desktop
bindsym $mod+l exec ~/.config/i3/lock.sh


Скрипт ~/.config/i3/lock.sh:


#!/bin/bash

# Make screenshot
scrot /tmp/screen.png

# Scale image
convert -scale 10% -scale 1000% /tmp/screen.png /tmp/screen1.png

# Clean
rm -f /tmp/screen.png

# Lock screen
i3lock -i /tmp/screen1.png


Выглядит это так:

Идем дальше по конфигу.


# Переключение между окнами:
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right


Я пропущу дальше секции про управление окнами, т.к. конфиг практически ничем не отличается от дефолтоного. Удаляем/комментируем секцию с i3bar.

Убираем декорации окон


# New window size
new_window pixel


Мультимедиа кнопки


# Pulse Audio controls
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +5% #increase sound volume
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -5% #decrease sound volume
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle # mute sound

# Sreen brightness controls
bindsym XF86MonBrightnessUp exec xbacklight -inc 20 # increase screen brightness
bindsym XF86MonBrightnessDown exec xbacklight -dec 20 # decrease screen brightness


Настройка гапсов


# Эта опция нужна для того, чтобы гапсы отключались, если на эркане всего одно окно.
smart_gaps on

gaps inner 5
gaps outer 2


Автозапуск приложений


# Обои
exec feh --bg-scale /usr/share/backgrounds/gnome/Godafoss_Iceland.jpg &
# Автоблокировка экрана через 2 минуты
exec xautolock -locker ~/.config/i3/lock.sh -time 2 &
# Апллет для управления network-manager
exec nm-applet &
# Композитор
exec compton &
# Conky
exec conky -c /home/d_zheleztsov/.conkyrc &
# Почему-то без такого костыля у меня dunst запускаться не хочет
exec killall dunst && dunst -conf /home/d_zheleztsov/.config/dunst &

# Изменение цветовой температуры в зависимости от времени суток
exec redshift &

# Запускаем приложения на своих рабочих столах
exec --no-startup-id i3-msg 'workspace 1; exec firefox'
exec --no-startup-id i3-msg 'workspace 2; exec gnome-terminal'
exec --no-startup-id i3-msg 'workspace 3; exec emacs25'
exec --no-startup-id i3-msg 'workspace 4; exec pidgin'
exec --no-startup-id i3-msg 'workspace 5; exec evolution'

# Панель
exec ~/.local/bin/polybar main &


По поводу конфигурации панели будет хорошо почитать официальную вики.

## Итоговые конфиги

* i3: ~/.config/i3/config
* polybar: ~/.config/polybar/config
* conky: ~/.conkyrc

## Что получилось

Ссылка: https://difrex.lessmore.pw/post/i3wm-config/

# Фест Эпоха рыцарства 2017
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:48


Будет много фоток. Пост весит 16Мб.

Под Минском в д. Озерцо проходил фестиваль "Эпоха рыцарства" на котором в первый день я и побывал.

Было солнечно и тепло. В палатках продовались домашняя медовуха и сбитень.

Уже на подходе к самому месту проведения заметили палатки и косплееров на коняшках.

Сам фестиваль проходил на территории музея народной архитектуры и быта. Там можно походить и заглянуть в некоторые из домов, где попытались воссоздать старинный быт. Ничего особо примечательного, но красиво.

Во второй половине дня начался турнир рыцарей. Это там, где они пиками друг-друга тыкают. Ведущий что-то постоянно рассказывал и комментировал.

Вышли сами рыцари с флагами и на конях.

Вот этот с гусем на голове был особо приколен.

Над этим всем летал дрон и снимал видео. Наверное, его где-то можно будет увидеть.

Рыцари скакали на лошадях и перепрыгивали через препятствие. Весело.

Высоко в небе периодически летали дельтопланы с которых тоже фотографировали фестиваль.

В конце турнира по сценарию рыцари поссорились и между ними начался махач.

За этим наблюдали красивые девочки в средневековых костюмах.

Вечером, на разогреве, выступали фолк-музыканты. Первыми вышли Hardwood.

Играли довольно неплохо, но вот этой графине походу неособо понравилось. Позади нее на фоне можно увидеть состязание эльфов-лучников.

Следующими выступали Стары Ольса. Подтянулись мужики в смешных шапках. Наверняка гномы.

Выступление проходило весело.

Барабанщики круты!

После Стары Ольса на сцену вышли Butterfly Temple. Пока они чекались сходил за сцену.

Клевые домики.

Средневековые девченки отошли за сцену покурить и початиться.

Наконец-то Butterfly настроились и зарубили МИТОЛ!

Чувак-ведущий залез на столб и пустился в пляс!

Выступление было драйвовым. Играли Butterfly Temple примерно час. На улице стемнело и температура воздуха опустилась всего до 12 градусов тепла. Комары озверели, в шортах находиться стало не очень круто и мы поехали домой в Минск.

Ссылка: https://difrex.lessmore.pw/post/fest-folk-museum/

# Отправляем логи в удаленный logstash
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:47


Все привыкли пользоваться связкой ELK. А что делать, если хочется отправить логи в уже существующий ELK с хоста на котором памяти в обрез?

У меня получилось так, что на виртуалке с сайтиком всего 512Мб памяти и логстешь при запуске просто выжирал ее всю и падал. Никакие Xmx Xms не помогали. Самое интересное, что логи-то nginx я заставил писать в JSON, а значит logstash выступает просто проксей до эластика.

Вот так можно заставить писать nginx в JSON. Добавляем это в nginx.conf.


log_format logstash_json '{ "@timestamp": "$time_iso8601", '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"body_bytes_sent": "$body_bytes_sent", '
'"request_time": "$request_time", '
'"status": "$status", '
'"request": "$request", '
'"request_method": "$request_method", '
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent" }';



А в конфиге сайта


access_log /var/log/nginx/access.log logstash_json;


Собственно пишем конфиг удаленного логстеша:


input {
tcp {
port => 12222
host => "10.8.0.10"
codec => "json"
}
}

output {
elasticsearch {
index => "nginx"
}
}


Теперь делаем скрипт отправки логов:


#!/bin/bash

# /usr/local/bin/logsend.sh

/usr/bin/tail -f /var/log/nginx/access.log | /bin/nc 10.8.0.10 12222


И запиливаем сервис systemd и стартуем его


[Unit]
Description=Send nginx log to remote logstash

[Service]
Type=simple
ExecStart=/usr/local/bin/logsend.sh

[Install]
WantedBy=multi-user.target


systemctl status logsend


● logsend.service - Send nginx log to remote logstash
Loaded: loaded (/etc/systemd/system/logsend.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2017-09-02 12:05:01 UTC; 1h 33min ago
Main PID: 28559 (logsend.sh)
Tasks: 3
Memory: 484.0K
CPU: 12ms
CGroup: /system.slice/logsend.service
├─28559 /bin/bash /usr/local/bin/logsend.sh
├─28562 /usr/bin/tail -f /var/log/nginx/access.log
└─28563 /bin/nc 10.8.0.10 12222


Использование памяти пол-мегабайта :).

Ссылка: https://difrex.lessmore.pw/post/logs-to-remote-logstash/

# Go в GNU Emacs
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:47


На самом деле это выжимка вот этой статьи. Ну, а еще некоторые вещи в ней устарели, по-этому немного обновленная версия.

# tl;dr

Поставим нужные пакеты в Емакс


(use-package exec-path-from-shell)
(use-package rainbow-delimiters)
(use-package go-snippets)
(use-package go-guru)
(use-package go-autocomplete)


Настроим go-mode


(use-package go-mode
;; Godef jump key binding
:bind (("M-." . godef-jump)
("M-*" . pop-tag-mark))
:init
(setenv "GOPATH" (concat (getenv "HOME") "/.local"))
:config
(defun set-exec-path-from-shell-PATH ()
(let ((path-from-shell (replace-regexp-in-string
"[ \t\n]*$"
""
(shell-command-to-string "/bin/bash -c '. ~/.bashrc && echo $PATH'"))))
(setenv "PATH" path-from-shell)
;; (setq eshell-path-env path-from-shell) ; for eshell users
(setq exec-path (split-string path-from-shell path-separator))))

(when window-system (set-exec-path-from-shell-PATH))

(defun my-go-mode-hook ()
"My Golang hook."
(setq gofmt-command "goimports")

;; Call Gofmt before saving
(add-hook 'before-save-hook 'gofmt-before-save)

;; Set compile command
(if (not (string-match "go" compile-command))
(set (make-local-variable 'compile-command)
"go build -v && go test -v && go vet"))

;; Enable rainbow
(rainbow-delimiters-mode-enable)
(auto-complete-for-go)
(yas-initialize))

;; Go autocomplete
(defun auto-complete-for-go ()
"Enable golang autocomple."
(auto-complete-mode 1))

(add-hook 'go-mode-hook 'auto-complete-for-go)
(add-hook 'completion-at-point-functions 'go-complete-at-point)
(add-hook 'go-mode-hook 'my-go-mode-hook)
(add-hook 'go-mode-hook #'rainbow-delimiters-mode))


Тут в :bind можно прописать свои сочетания клавиш.

Да, всегда используйте use-package. Это сэкономит кучу времени в будущем.

Теперь добавим GOPATH в ~/.bashrc


echo 'export GOPATH=${HOME}/.local' >> ~/.bashrc
. ~/.bashrc


Выкачиваем зависимости Go


go get -t -v golang.org/x/tools/cmd/goimports
go get -t -v golang.org/x/tools/cmd/guru
go get -t -v github.com/rogpeppe/godef


Готово. Код конфига доступен по ссылке.

Ссылка: https://difrex.lessmore.pw/post/go-v-emacs/

# API поиска на dynamic.lessmore.pw
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:46


## Поиск на dynamic.lessmore.pw

Как это ваще устроено??? На самом деле API - это открытый всем Elasticsearch, который предоставляет гору возможностей для поиска за счет движка Lucene. Давайте что-нибудь найдем!

Вот в этом вот комменте я пообещал рассказать как это все сделать. Приступим.

Давайте для начала попробуем поискать этот самый коммент: ii://XWShDDcuR4C8PcrTFdGl. Здесь и далее мы будем использовать только curl.


curl -XPOST -d '{"query": {"query_string" : {"fields" : ["msgid"], "query" :"XWShDDcuR4C8PcrTFdGl"}}}' https://dynamic.lessmore.pw/search


Нам вернется такой вот ответ


{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 8.316952,
"hits": [
{
"_index": "idec_net",
"_type": "post",
"_id": "XWShDDcuR4C8PcrTFdGl",
"_score": 8.316952,
"_source": {
"echo": "idec.talks",
"subg": "Re: Совет нодов",
"to": "Peter",
"author": "Difrex(mobile)",
"message": "\nПостараюсь завтра написать пост с обзором в ii://develop.16. Ну, и ссылку в этот тред скину.",
"date": "1513020107",
"msgid": "XWShDDcuR4C8PcrTFdGl",
"tags": "",
"repto": "h97Frgqdtapl4AI11aUj",
"address": "tavern,23"
}
}
]
}
}


Вот и он!

Нам вернулось одно сообщение, что не удивительно, т.к. ID в сети уникальны, а мы искали именно по нему.

А теперь давайте выведем все последние(5) сообщения(по дате) из эхи idec.talks:


curl -XPOST -d '{"sort": [{"date": {"order": "desc"}}, {"_score": {"order": "desc" }}], "size": 5}' https://dynamic.lessmore.pw/search -H 'Content-type: application/json'
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
}
...


Смотрите, тут мы отсортировали(на стороне сервера) сообщения по дате в порядке убывания и ограничили лимит в 5 сообщений. Попробуйте перевести это на SQL(`select * from idec.talks order by date desc limit 5`).

А теперь выполним более сложный поиск: мы найдем сообщения по строке! Т.е. выполним полнотекстовый поиск!

Запрос будет выглядеть так:


{
"sort": [
{
"date": {
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
}
],
"query": {
"simple_query_string": {
"query": "обзор"
}
},
"size": 5
}


Отправляем его POST-ом в https://dynamic.lessmore.pw/search.

В ответ нам на это вернется список из 5 сообщений отсортированных по дате, где найдены вхождения слова "обзор". Кстати, верхнее сообщение(b2rhH6sOfzEzgGZzLT51(на данный момент)) из эхи habra.16 и с заголовком "Обзор литературы по языку Python для начинающих".

Вот так вот. Чтобы делать более лучшие вещи читайте документацию(query DSL) по Elasticsearch.

// Да, если вашей эхи нет в индексе, то убедитесь, что она есть в list.txt

Ссылка: https://difrex.lessmore.pw/post/api-poiska-na-dynamic/

# Про IDEC
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:42


IDEC - это протокол обмена сообщениями совместимый на базовом уровне с ii. Расшифровывается, как ii-like Data Exchange Convention. Главная фишка его - это простота и возможность работать поверх чего угодно, например, ssh. Но практически все реализации сейчас работают поверх http.

Цитата из официальной документации

> Есть несколько серверов (грубо говоря, сайтов), за каждым из которых закреплены свои пользователи (поинты). Поинты пишут сообщения каждый на свой сервер. Через каждые 10-20 минут сервера скачивают друг у друга новые сообщения. В итоге на всю сеть одна общая база данных. Для установления цепочек синхронизации владельцы серверов сначала договариваются.
>
> Всё общение разделено на так называемые эхоконференции или эхи (см. терминология). Эха - это что-то вроде ленты твиттера или темы на форуме. Пользователи могут свободно подписываться на интересные им эхи и писать туда сообщения в пределах одной станции. Держатели серверов синхронизируют между собой (по общему согласию) самые популярные и нужные пользователям эхи, и сообщения оттуда расходятся по всей сети.

Так при отключении одного из серверов, сообщения останутся живы на других, что дает нам такие блага, как антицензурируемость и отказоустойчивость.

## Общение

В стандарте предусмотрена очень полезная фича, как /list.txt(это может быть на самом деле файл или путь в строке адреса в браузере). На запрос list.txt сервер возвращает нам список эх(публичных) с описанием и количеством сообщений в них. Так при первом попадании на сервер, клиент сможет сразу знать какие эхи он хочет читать.

Стандарт и все реализации серверов поддерживают создание эхи пользователем. Для этого нужно всего лишь написать в нее. Такая эха не будет отображаться в list.txt и получить из нее сообщения можно, только зная название. Шифрования в стандарте нет, но это и не нужно, ибо приносит только усложнение. Для приватного общения можно использовать скрытую эху и GPG.

Личных сообщений нет, но обсуждение стандарта идет. Можно начать с чтения этого треда.

Каждое сообщение в сети уникально, т.е. ему присвается ID сгенерированный на основе суммы sha256 от контента. Это не спасает от спама, но позволяет избежать коллизий в сети.

## Устройство сети

На протоколе IDEC чаще всего реализуют децентрализованную клиент-сервер сеть. P2P не предусмотрено, но никто не мешает написать свое расширение, которое реализует P2P обмен.

Итак, рассмотрим топологию сети от простого к сложному.

Самая простейшая сеть выглядит так:

У нас есть два клиента, которые обмениваются сообщениями через сервер. Оба клиента получают сообщения из одной и той же эхи. Все централизовано и при смерти сервера клиенты больше не смогут общаться с друг дугом. Давайте добавим еще один сервер!

Владельцы серверов договорились между собой обмениваться сообщениями эхи pipe.2032, теперь при выходе из строя одного из серверов сообщения будут доступны на другом сервере.

Добавим еще сегмент сети

У нас добавился еще один сегмент сети в котором происходит общение в эхах pipe.2032 и linux.14. Так наш первый сегмент начинает обмениваться сообщениями со вторым. Добавим еще один сегмент.

И еще

Можно еще добавить связь между серверами внутри кольца и мы получим полностью децентрализованную сеть, которая реализует распределенную базу данных.

IDEC позволяет строить любые топологии. Клиент может выступать так же и сервером и забирать сообщения сразу со всех серверов. А простота протокола позволяет писать ботов очень быстро.

В следующей статье напишем бота, который будет слать сообщения в указанную нами эху.

Ссылка: https://difrex.lessmore.pw/post/pro-idec/

# eshell в качестве шелла
difrex.blog
Difrex(mobile)(tavern,23) — All
2018-07-30 07:40:39


Я тут подумал: а чей-то я использую в качестве шелла zsh, когда можно юзать емаксовый eshell?

Быстренький гайд.

## Делай раз

Для начала, чтобы темы отображались правильно нужно сгенерировать terminfo. В 26.1 емаксе можно работать с 24-битным терминалом. Напишем файл terminfo-24.src:


# Use colon separators.
xterm-24bit|xterm with 24-bit direct color mode,
use=xterm-256color,
setb24=\E[48:2:%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm,
setf24=\E[38:2:%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm,
# Use semicolon separators.
xterm-24bits|xterm with 24-bit direct color mode,
use=xterm-256color,
setb24=\E[48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%dm,
setf24=\E[38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%dm,


Генерируем:


tic -x -o ~/.terminfo terminfo-24bit.src


Экспортируем переменную окружения:


export TERM=xterm-24bit


Теперь при запуске GNU Emacs в терминале(`emacs[client] -nw`) вместо покореженных цветов при `TERM=xterm-256color`

будет красиво

Это тема solarized-dark, кстати.

## Делай два

Но запускать Емакс в терминале при наличии иксов несколько странно. По-этому нужно пускать сразу `(eshell)`. В параметрах терминала в качесте комманды прописываем `/bin/sh -c "export TERM=xterm-24bit; emacsclient -nw -c -e \"(eshell 'N)\""` и у нас будет сразу пускаться eshell. Неплохо, не правда ли? :)

Либо можно пойти еще дальше и перебиндить стандартнуй комбинацию клавишь на запуск сразу eshell в графическом Emacs. Так, например, для i3wm: `bindsym $mod+Return exec emacsclient -c -e "(eshell 'N)"`.

Ура!

Ссылка: https://difrex.lessmore.pw/post/eshell/

# Re: Что с станцией lessmore?
idec.talks
hugeping(ping,1) — Difrex
2020-09-14 20:21:52


> У меня тоже. Но это все таки данные не совсем для человека.

Ну как, curl можно автоматизировать. Я так и делал, когда переносил данные с ноды, генерировал скриптом запросы, парсил вывод. Удобнее с \n это делать.

> Ты же не будешь править тело сообщения поинта если оно пришло без \n в конце, а просто запишешь в базу.

Лучше я промолчу о том, что я делаю с сообщением поинта, а то вы меня тут заклюёте =)

> // Newline в конце добавлю, но фетчер у меня умеет и так и так.

Угу, отпишись тогда, я от тебя хочу взять fetch difrex.blog (ну и назад забирай тогда её у меня =)

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — Andrew Lobanov
2020-09-14 19:41:40


> У меня даже emacs в файлах в конце '\n' ставит :)
У меня тоже. Но это все таки данные не совсем для человека.

Ты же не будешь править тело сообщения поинта если оно пришло без \n в конце, а просто запишешь в базу.

// Newline в конце добавлю, но фетчер у меня умеет и так и так.

# Re: Что с станцией lessmore?
idec.talks
vit01(mira, 1) — Difrex
2020-09-14 15:25:51


Difrex> Т.е. я считаю, что "\n" - это разделитель списка и если в конец вносить его, то получится, что последний элемент списка - это всегда пустая строка.

В стандарте вроде про newline ничего не сказано, поэтому предусматривается, что "\n" - это лишь разделитель списка, и в конце он необязателен

В нодах и клиентах принято использовать логику, по которой принимают и то, и другое. Но, думаю, для лучшей совместимости с unix-утилитами стоит явно закрепить в стандарте, чтобы newline в конце присутствовал

+++ Отправлено через IDEC Mobile
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Что с станцией lessmore?
idec.talks
Andrew Lobanov(tavern,1) — Difrex
2020-09-14 14:59:18


Difrex> Ну, в общем давай подождем остальных, что скажут. По мне так '\n' в конце списка эх необязателен, т.к. не относится к данным.

'\n' в конце это однозначное и ожидаемое поведение. Мне кажется, что делать стоит единообразно. У меня даже emacs в файлах в конце '\n' ставит :)

# Re: Что с станцией lessmore?
idec.talks
hugeping(ping,1) — Difrex
2020-09-14 14:28:11


> Т.е. я считаю, что "\n" - это разделитель списка и если в конец вносить его, то получится, что последний элемент списка - это всегда пустая строка.

Мой довод, в основном, будет таким.

В UNIX все текстовые файлы традиционно заканчиваются на \n.

https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline

Стандарт POSIX определяет строку так:

> 3.206 Line
> A sequence of zero or more non- <newline> characters plus a terminating <newline> character.

Зафиксируем это и не ошибёмся. :)

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — Difrex
2020-09-14 13:35:35


Т.е. я считаю, что "\n" - это разделитель списка и если в конец вносить его, то получится, что последний элемент списка - это всегда пустая строка.

Но в случае чего, я могу добавить перенос строки.

> В системе, когда у нас последняя строка не содержит \n, мы не можем отличить ситуацию, прочиталась ли строка целиком?
Это справедливо только для имен эх, а вот id сообщения всегда можно понять прочитался ли он полностью.

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — hugeping
2020-09-14 13:29:10


Ну, в общем давай подождем остальных, что скажут. По мне так '\n' в конце списка эх необязателен, т.к. не относится к данным.

# Re: Игра R01
std.game
boscholeg(ping,5) — hugeping
2020-09-14 13:32:58


Это прямо какой-то супер-блиц.
Я думаю критикой Андрея не испугать. Он и так знает, что ему скажут и почему.
Все-же выскажу:
Игре явно не хватает иллюстраций, пусть даже карандашных и самых простых. Игра про космос должна быть с картинками звезд (сугубо лично мое мнение).
Отсутствует некая предыстория. Думаю тут просто не хватило времени.
Игра очень быстро кончилась я не успел даже разыграться как следует.
Наличие счета немного смутило. Не ясно зачем он и к чему мотивирует.

С музыкой получилось непонятно. Трек состоит из вдух музыкальных тем и вторая тема несколько противоречит по настроению первой.

Андрей большой молодец его работы всегда заставляют игрока живо реагировать и испытывать целый спектр эмоций. Я к тому-же с удовольствием разглядываю исходники. Игра может войти в список игр для МШВ и вполне сгодится для первого знакомства с жанром у подрастающего поколения.

# Игра R01
std.game
hugeping(ping,1) — All
2020-09-14 10:58:13


Прошёл игру-миниатюру R01 от Andrew Lobanov, которую он написал на Паровозик.

Сама игра здесь: http://instead-games.ru/game.php?ID=349

Когда начал играть, сразу понял -- мне нравится! В этом посте, на примере этой зарисовки, я хочу поделиться некоторыми соображениями по поводу "рецепта успеха хорошей игры".

Конечно, в рецепты я не верю, но у игры Андрея есть ворох качеств, которые очень характерны для определённого типа игр, которые мне по душе.



# Музыка.

Я из тех людей, для которых музыка в игре или фильме имеет значение, чуть ли не большее, чем само произведение. В этой игре музыка просто 1 в 1 ложится так, как надо. Подобрать музыку тоже нужно уметь. Кстати, кто знает, возможно успех Кота это в большей степени заслуга трекерной музыки?

# Сказка

Да! Это сказка! Событий много, с лёгкой руки автора они сыпятся и сыпятся. Правдоподобность? Реализм? Это всё вообще не колышет. Вы ещё спросите, как летают X-wing в атмосфере с такими кабинами (фонарями, на жаргоне пилотов) и антеннами. Или почему в космосе слышны звуки. Это сказка! Как сказка и воспринимается! Очень люблю такой вот формат.

Часто меня упрекали за "картонность" персонажей в Коте. Тут тоже, персонажи выписаны кратко и картонно, что совершенно уместно в сказке. Зато мы имеем череду событий и сцен, которые не дают нам скучать.

# Плотность предметов на сцену

Часто замечаю (да и за собой тоже), как авторы злоупотребляют количеством объектов на сцене. Да, INSTEAD может и провоцирует это, но чувство меры и здравого смысла должно сдерживать автора. Когда на сцене у нас больше 3-5 ссылок-объектов или 3-4 переходов, становится сложно воспринимать игру.

Мне нравится, когда повествование "размазано" по локациям. Ходить интересно! Исследовать пространства - интересно! Это же адвенчура! И в R01 есть это чувство меры.

Может быть, конечно, причиной этого стали жёсткие сроки, но в результате - играть забавно и ненапряжно. В общем, мне кажется не надо бояться делать "пустые" локации, расширяя игру в пространстве за счёт геометрии, а не плотности предметов и высокой степени комбинаторики.

# Чего не хватает?

Моя вечная претензия - резкое обрубание в конце. Хотя, я уже привык и воспринимаю это как "авторский приём". И конкретно здесь, смотрится нормально. Но всё-таки, я люблю когда в конце игры есть повод задержаться.

Пару миниатюрных иллюстраций украсило бы игру ещё больше. Может быть как раз одна/две картинки на финальных сценах игры/титрах.

P.S. Автор, пиши ещё!

# Re: Что с станцией lessmore?
idec.talks
hugeping(ping,1) — Difrex
2020-09-14 10:11:34


> А почему так? Я код не хочу ща читать - лень, но ты разве не разбираешь ответ в слайс? Типа,

Почему так, вопрос, который я тоже могу задать: "Разве ты не делаешь просто Printf каждого из id? Зачем вырезать последний \n?

Дело в том, что я старался писать строго. Строка с переводом строки - это однозаначность. Например, пустая строка - это тоже пустая строка и \n.

В системе, когда у нас последняя строка не содержит \n, мы не можем отличить ситуацию, прочиталась ли строка целиком?

Например, вот функция, которая используется везде при работе с сетью:

func http_req_lines(url string, fn func(string) bool) error {
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	reader := bufio.NewReader(resp.Body)
	for {
		line, err := reader.ReadString('\n')
		if err != nil && err != io.EOF {
			return err
		}
		line = strings.TrimSuffix(line, "\n")
		if err == io.EOF {
			break
		}
		if !fn(line) {
			break
		}
	}
	return nil
}

Обрати внимание, что if err === io.EOF стоит ПЕРЕД fn(line).

А вот правка, чтоб сработало с твоей нодой:

                if err == io.EOF {

			if line != "" { /* no eol in last line? broken node? */
				fn(line)
			}
                        break
                 }

Если же я перенесу fn(line) перед err == io.EOF, то fn(line) будет вызываться для последнего \n у других нод, которые делают \n в каждой строке.

Я лично считаю, что \n быть должен, но в как бы мы не решили, это должно быть прописано в стандарте, кмк.

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — hugeping
2020-09-14 08:57:21


> Мне не сложно подправить, но это именно будет хак. Дополнительный блок условный.
А почему так? Я код не хочу ща читать - лень, но ты разве не разбираешь ответ в слайс? Типа,

messages := make(map[string][]string)
echoList := strings.Split(getBody(resp.Body))
var currentEcho string
for i := range echoList {
  if echoList[i] == "" {
    continue
  }
  if isEcho(echoList[i]) {
    currentEcho = echoList[i]
  }
  if isMessage(echoList[i]) {
    messages[currentEcho] = append(messages[currentEcho], echoList[i])
  }
}

# Re: Что с станцией lessmore?
idec.talks
hugeping(ping,1) — Difrex
2020-09-14 07:40:15


> Хм, вот про newline в конце интересно. Это у нас нигде не описано, но и проблем ни у кого не возникало

Нужно решение комитета. )
Мне не сложно подправить, но это именно будет хак. Дополнительный блок условный. Заметил только благодаря адаптивному фетчу, который делает пробы по 1 id. Так бы просто последнее сообщение бы не взял и всё.

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — hugeping
2020-09-14 06:54:27


Хм, вот про newline в конце интересно. Это у нас нигде не описано, но и проблем ни у кого не возникало

# Re: Пишу ноду ii/idec на go
idec.talks
vit01(mira, 1) — hugeping
2020-09-14 00:59:21


hugeping> Достаточно ли замены:
hugeping> ====
hugeping> msg = strings.Replace(msg, "-", "+", -1) /* if it is URL base64 */
hugeping> msg = strings.Replace(msg, "_", "/", -1) /* make it base64 */
hugeping> ====
hugeping> И потом декодировать стандартным base64? Но там вроде еще есть заполнение в виде ===?

Должно быть достаточно. А заполнение как было знаками равно, так и должно вроде как остаться таковым

+++ Отправлено через IDEC Mobile
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Что с станцией lessmore?
idec.talks
hugeping(ping,1) — Difrex
2020-09-13 21:53:55


> Fixed
Теперь есть другая проблема. Возможно, с моим фетчером.
В выводе у тебя нет последнего перевода строки. То-есть, на запрос -1:1, к примеру, приходит MsgId без \n. Как к этому относиться? Нужно ли мне переделывать?

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — hugeping
2020-09-13 20:37:29


Fixed

# Plan9 Desktop Guide
std.hugeping
hugeping(ping,1) — hugeping
2020-09-13 20:32:27


Похоже, интересная статья. Оставлю для ознакомления.

https://pspodcasting.net/dan/blog/2019/plan9_desktop.html

# Re: Что с станцией lessmore?
idec.talks
Difrex(dynamic,1) — hugeping
2020-09-13 17:26:43


Хм. Это я сломал что-то в базовом протоколе :).

Работает только со смещением сейчас
curl https://dynamic.lessmore.pw/idec/u/e/difrex.blog/-250:250
difrex.blog
2fDZ67P8JkchA9Rh4If4
2NszlFTgvhakzz7dIfvc
ML8cpSyzyOKaFA6Lx1NF
8TtPHu5T7oo3GSXdDYc5
U6ZYZxgYz2sq01L96zZz
igt9lCsui5qE9AICtdgP
mTWsJXVOAljita3sgDOK
V0hj3Z0QjFxpluaaiKvI
b91aGfRgRLJWfB1q60bg
pNfzXBddGbSy7AW7slpz
4fmEizz5kjk4UcQf7VIJ
OxdmEiQJIZqrqjCUNp2i
ojRAXNp7wzVIF9GBetZn
z5UV57mUeyhAmFsaMUq0

Спасибо, поправлю.

# Re: Пишу ноду ii/idec на go
idec.talks
hugeping(ping,1) — hugeping
2020-09-13 18:03:07


Достаточно ли замены:

msg = strings.Replace(msg, "-", "+", -1) /* if it is URL base64 */
msg = strings.Replace(msg, "_", "/", -1) /* make it base64 */

И потом декодировать стандартным base64? Но там вроде еще есть заполнение в виде ===?

# Re: Пишу ноду ii/idec на go
idec.talks
hugeping(ping,1) — vit01
2020-09-13 17:26:04


> Да, именно так, надо детектить, но это просто делается: всего лишь прогоняешь строку через замену символов, заменяя спецсимволы по словарю.

Можно этот момент описать подробнее. Каким алгоритмом base64 декодировать и что на что заменять? Я немного посмотрел, разница в стандартах base64 не такая маленькая, как мне показалось, чтобы решить её заменой. Но похоже, я ошибся.

Можно рассказать алгоритм?

# Re: Пишу ноду ii/idec на go
idec.talks
vit01(mira, 1) — hugeping
2020-09-13 17:00:05


hugeping> Это про msgid речь же. А вопрос вроде касался того, в каком формате поинт шлёт бандл на ноду (POST или GET, не важно). И в каком формате отдают/получают бандлы ноды.

Для поинтов политика такая: если пересылает через GET, значит обязательно urlsafe. Если через POST, то поинт может выбрать любой вариант, какой захочет, ведь нода обязана поддерживать и тот, и другой

hugeping> В стандарте есть такая фраза: (все серверы обязаны принимать как обычный, так и urlsafe-словарь, генерируются же бандлы в формате обычного base64)

hugeping> Для меня эта фраза непонятна. Бандлы вроде в обычном base64, но принимать я должен в любом? Надо детектить тип base?

Да, именно так, надо детектить, но это просто делается: всего лишь прогоняешь строку через замену символов, заменяя спецсимволы по словарю.

То есть ещё раз: принимать нужно оба формата одновременно, но генерировать на отдачу желательно (как необязательная рекомендация) в обычном base64

+++ Отправлено через IDEC Mobile
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Пишу ноду ii/idec на go
idec.talks
hugeping(ping,1) — vit01
2020-09-13 15:48:57


>> Примечание: production-реализации нод заменяют в полученной base64-строке плюс (+) и слэш (/) либо их аналоги (- и _) на буквы "A" и "Z" соответственно, дабы убрать из msgid спецсимволы.

Это про msgid речь же. А вопрос вроде касался того, в каком формате поинт шлёт бандл на ноду (POST или GET, не важно). И в каком формате отдают/получают бандлы ноды.

В стандарте есть такая фраза: (все серверы обязаны принимать как обычный, так и urlsafe-словарь, генерируются же бандлы в формате обычного base64)

Для меня эта фраза непонятна. Бандлы вроде в обычном base64, но принимать я должен в любом? Надо детектить тип base?

Я так и не понял, в каком варианте base64 я должен принимать и отдавать бандлы нодам и принимать бандлы от юзера. В итоге имеем такие варианты:

Мой:
1) Я принимаю и отдаю нодам бандлы в обычном base64 (не считая msgid, который подвергается преобразованию описанному в стандарте)

2) принимаю post/get запросы от поинтов в urlsafe base64

И вроде это работает, по крайней мере со станцией Андрея.

difrex:

1) принимает от поинтов обычный base64 но предварительно заэскейпченный

На мой взгляд, противоречит стандарту. Но я так и не понял, как правильно.

# Re: Пишу ноду ii/idec на go
idec.talks
vit01(mira, 1) — Andrew Lobanov
2020-09-13 14:36:04


>>>> @repto вместо @Repto
Difrex>>> Разве у нас в стандарте с большой буквы прописано? В тех же iing и ii-php реализованно с маленькой.
vit01>> Всегда было с маленькой. Глянул в документацию - оказалось, что Github стал неправильно рендерить Markdown, и там отображается с большой, хотя в исходнике осталось всё как надо

Наконец-то исправил, чтобы норм отображалось.

>>>> StdBASE64 вместо URLBase64 в get запросе
Difrex>>> Там ескейпится потом. Не помню уже почему именно так сделано было.
vit01>> Для кодирования самого сообщения вроде как раз urlbase64 и используется. Для хэшей же идёт полная подмена символов, чтобы избежать знаков препинания

AL> Из документации это не следует никоим образом.

Цитирую: https://ii-net.tk/idec-doc/?p=standarts

> Id сообщения (msgid) - уникальный номер, который генерируется станцией, как 20 первых символов base64 sha256-bin хэша сообщения.

> Примечание: production-реализации нод заменяют в полученной base64-строке плюс (+) и слэш (/) либо их аналоги (- и _) на буквы "A" и "Z" соответственно, дабы убрать из msgid спецсимволы.

+++ Отправлено через IDEC Mobile
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Пётр шевелит секту
pipe.2032
Andrew Lobanov(tavern,1) — vmg
2020-09-13 11:02:05


vmg> Я только не понял про caesium. Будет ли он жить.

Цезий останется в таком виде, в каком он есть сейчас. В планах есть новый консольный клиент, написаный с нуля, но это большой труд и пока некогда за него взяться.

Сам я пользуюсь и пилю сейчас http://github.com/spline1986/idec-client

# Re: Пётр шевелит секту
pipe.2032
artur(ping,3) — hugeping
2020-09-13 08:40:51


А идея с тематическими темами очень даже. Но опять же, зависит от планов.

# Re: Пётр шевелит секту
pipe.2032
vmg(tavern,32) — hugeping
2020-09-13 08:32:32


hugeping> Наверное надо где-нибудь писать про idec, все-таки. Думаю все присутствующие узнали про ii из постов на лор или чего-то подобного?

Мне как сектанту-обывателю интересны новости из мира информатики и вычислительной техники, которые прилетают сюда из opennet и, конечно, наша подпространственная связь. Есть в этом что-то правильное.
Я только не понял про caesium. Будет ли он жить.

# Re: Пётр шевелит секту
pipe.2032
hugeping(ping,1) — Andrew Lobanov
2020-09-13 08:03:01


> Этак скоро скрипт статистики снова будет иметь смысл :)

Наверное надо где-нибудь писать про idec, все-таки. Думаю все присутствующие узнали про ii из постов на лор или чего-то подобного? Ну или организовывать тематические сообщества: инстед, план9 итд.

С другой стороны, у меня лично цели нет "набрать поинтов".

# Пётр шевелит секту
pipe.2032
Andrew Lobanov(tavern,1) — All
2020-09-12 22:01:34


Этак скоро скрипт статистики снова будет иметь смысл :)

# Re: Переезд состоялся
std.hugeping
artur(ping,3) — hugeping
2020-09-12 20:31:09


Ну это само-собой разумеющееся=)

# Re: Переезд состоялся
std.hugeping
hugeping(ping,1) — artur
2020-09-12 20:30:35


> Понял-принял. Ну тогда уж надо будет поделиться здесь своими пиксельными поделищами=)

Только просьба, не в этой эхе (std.hugeping), потому что здесь мой блог. :)

# Re: Переезд состоялся
std.hugeping
artur(ping,3) — hugeping
2020-09-12 20:27:41


Понял-принял. Ну тогда уж надо будет поделиться здесь своими пиксельными поделищами=)

# Re: Переезд состоялся
std.hugeping
hugeping(ping,1) — artur
2020-09-12 20:25:02


> Вопрос на счёт картинок с постов. В Гимпе рисовано?=)

Потому что я уменьшаю разрешение до 32x32 и режу количество цветов. Тогда картинка xpm смотрится нормально и в тексте сообщения. А так, это просто пиксельарт из интернетов.

# Re: Пишу ноду ii/idec на go
idec.talks
hugeping(ping,1) — vit01
2020-09-12 20:22:00


> Предлагаю прописать font-family: sans-serif в body-блок CSS-ки. Это сработает на всех платформах, и разница станет заметна невооружённым глазом. Попробуй хотя бы ради эксперимента

Вообще, я пробовал. Но тут такое дело. Я не хочу навязывать sans/sans-serif. Я сам из тех, кто долго верил в теорию вреда "шрифтов с засечками". А потом попробовал засечки, и мне понравилось. Поэтому я не хочу навязывать стиль шрифта. Пусть отображается дефултная настройка браузера. Те, если у тебя стоит в дефолте шрифты с засечками, ты их и увидишь. Есть вопрос с мобильными браузерами, там такой настройки нет... Ну, что поделать.

# Re: Пишу ноду ii/idec на go
idec.talks
vit01(mira, 1) — Andrew Lobanov
2020-09-12 19:38:05


vit01>> 1. Нужно всё-таки объединять усилия, приходить к некоторым компромиссам и пилить одну библиотеку на всех. А аргумент "хочу другую лицензию" хоть и имеет смысл на существование, но на благо проекта точно не пойдёт. Кому-то из вас двоих нужно от своей репы отказаться и идти мержить код в общий котёл

AL> Лицензионные вопросы важны.

Здесь я ничего не навязываю, а просто предложил дискуссию и вижу проблему в распылении ресурсов. Если юзкейс каждой из либ слишком специфичен, то мержить и правда не имеет смысла

vit01>> 2. Лично мне хотелось бы не новой ноды, а нормального десктопного клиента. С избранными, с черновиками, с красивым современным интерфейсом...
AL> Всё от того, что ты хочешь пальцетыкательный интерфейс на десктопе, что, очевидно, моветон.

Дело здесь не в пальцетыкальности, а в двухпанельности и "просмотре по одному". Когда ты читаешь сообщения с большим количеством текста, то с ними удобнее возиться по отдельности и отвечать на них по отдельности, а не скроллить сплошную стену текста. При этом держать перед глазами заголовки сообщений

На Андроиде это хорошо сделано в стандартном емейл-приложении (или в GMail, где тот же интерфейс). На десктопе - Thunderbird, Apple Mail, Outlook, и.т.п. Просто в плане общения IDEC слишком похож на Email, чтобы избежать такого сравнения

vit01>> И да, шрифты говно. Не стал бы пользоваться новым интерфейсом просто из-за шрифтов с засечками. Так и людей распугать можно
AL> Перепутал вкусовщину с объективностью.

Это, конечно, грубо сказано было (и весьма в лоровском стиле, к сожалению), но тут тоже проблема просматривается и как раз объективная.

Особенность шрифтов без засечек - это то, что они не замыливают глаза и делают возможность "чтения по диагонали", что очень важно для контролов и других вспомогательных элементов интерфейса. А шрифты с засечками используют в книгах, потому что текст с ними сильнее въедается в мозги и вроде как лучше усваивается, но зато напрягает глаза

В современном веб-дизайне не просто так сложился консенсус, что шрифты без засечек лучше использовать по максимуму, а потому что это действительно читаемее. Кроме того, важен и размер шрифта, но это уже совсем другая история.

+++ IDEC Mobile в виртуальной машине
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Пишу ноду ii/idec на go
idec.talks
vit01(mira, 1) — hugeping
2020-09-12 19:38:06


>> 1. Нужно всё-таки объединять усилия .... Кому-то из вас двоих нужно от своей репы отказаться и идти мержить код в общий котёл

hugeping> Это не сработает. Мне нравится писать то, что мне нравится. Это наверное основная движущая сила "моего опенсорца". Но никто не мешает брать мой код, если он нужен. Мой замысел в принципе не компромиссный. Потому что я хотел сделать не "что-то усреднённо хорошее", а ноду своей мечты. И нода и либа и веб морда готовы - их можно просто брать и использовать, если нравится. Если нет - делать своё.

Окей, вопрос в каком-то смысле исчерпан

>> И да, шрифты говно. Не стал бы пользоваться новым интерфейсом просто из-за шрифтов с засечками. Так и людей распугать можно
hugeping> Шрифты вообще не заданы нигде. Никакие. Так что используется тот шрифт, что стоит у тебя в настройках. :)

Эмм, да, но у браузера даже для стандартных шрифтов есть опции.

Предлагаю прописать font-family: sans-serif в body-блок CSS-ки. Это сработает на всех платформах, и разница станет заметна невооружённым глазом. Попробуй хотя бы ради эксперимента

+++ IDEC Mobile в виртуальной машине
+++ GNU/Linux, Android, physics, MLP:FIM

# Re: Переезд состоялся
std.hugeping
artur(ping,3) — hugeping
2020-09-12 20:09:02


Вопрос на счёт картинок с постов. В Гимпе рисовано?=)
Выглядит очень простенько. Чем-то напоминает картинки из третьего ИНСТЕДОЗа.

# Что с станцией lessmore?
idec.talks
hugeping(ping,1) — All
2020-09-12 18:55:16


Хотел было забрать блог difrex, но:

$ curl https://dynamic.lessmore.pw/idec/u/e/difrex.blog
difrex.blog
error: Internal error

# ZeroNet приложение для Android
std.hugeping
hugeping(ping,1) — hugeping
2020-09-12 18:37:00


Оказывается, за то время, что я не следил за ZeroNet, в PlayMarket появилось новое приложение. Выглядит оно получше и поудобнее. Что косвенно подтверждается оценкой приложения.

Так что относительно комфортно можно пользоваться ZN и с мобильных устройств.

Мой блог в ZN: http://127.0.0.1:43110/1HVhvrompfwLstJExofKAQ5mMss7YivVDj/

Правда, теперь там будут скорее всего только репосты с узла ping.