Намагаюся частіше використовувати фічі останніх стандартів C++, зокрема ranges. Тож у мене доволі багацько коду на кшталт такого:
Але рядок швидко стає немаленьким завширшки, особливо з плюсовим синтаксисом, як ви можете собі уявити. А clang-format форматує код отак:
Тобто пайп ставить в кінці рядка, а наступний рядок починає під початком першого слова у виразі. Тут для краси
Для clang-format
Дратувало мене це — просто жах, але як так налаштувати його, щоб у мене око не тіпалося — хз. Вирішив спитати #ШІ, бо думав, може, пропустив якесь спеціальне налаштування на цей випадок. А ШІ-шка мені: «так ти просто коментар порожній в кінці рядка лишай»🤯
Тепер clang-format бачить, що між операндом та пайпом ще токен коментаря стоїть, і йому доводиться писати пайп з нового рядка )
Так, ШІ-шка цьому десь навчилася теж, але я сам щось не допетрав до такого рішення.
return mimeData->formats() | views::transform(toMimeSlice) | to<Clip::MimeContainer>();
Але рядок швидко стає немаленьким завширшки, особливо з плюсовим синтаксисом, як ви можете собі уявити. А clang-format форматує код отак:
return mimeData->formats() |
views::transform(toMimeSlice) |
to<Clip::MimeContainer>();
Тобто пайп ставить в кінці рядка, а наступний рядок починає під початком першого слова у виразі. Тут для краси
toMimeSlice
просто як функція передається, але насправді там могла бути лямбда на декілька рядків, і це зовсім неможливо стає читати.Для clang-format
|
— це просто бінарний оператор. Можна, мабуть, налаштувати, щоб він у довгих виразах починав рядок з нього, але тоді він це буде робити і для якогось +
, а мені так не подобається.Дратувало мене це — просто жах, але як так налаштувати його, щоб у мене око не тіпалося — хз. Вирішив спитати #ШІ, бо думав, може, пропустив якесь спеціальне налаштування на цей випадок. А ШІ-шка мені: «так ти просто коментар порожній в кінці рядка лишай»
return mimeData->formats() //
| views::transform(toMimeSlice) //
| to<Clip::MimeContainer>();
Тепер clang-format бачить, що між операндом та пайпом ще токен коментаря стоїть, і йому доводиться писати пайп з нового рядка )
Так, ШІ-шка цьому десь навчилася теж, але я сам щось не допетрав до такого рішення.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3😁1😭1🙈1
Сьогодні компілятор мене тролить. Пишу, знач, у себе в коді:
А він мені:
«Не можу», — каже, — «справа від
А він у відповідь:
Короч, зліва теж не можна. Чого одразу не сказати щось на кшталт «не пиши initializer list в тернарніку»‽ Як у тому анекдоті про програмістів — максимально точна відповідь, яка, втім, не несе жодної користі.
QHash<int, QByteArray> roles = sourceModel() ? sourceModel()->roleNames() : {};
А він мені:
PaddingProxyModel.cpp:695:76: error: initializer list cannot be used on the right hand side of operator ':'
QHash<int, QByteArray> roles = sourceModel() ? sourceModel()->roleNames() : {};
^ ~~
«Не можу», — каже, — «справа від
:
поставити {}
». Ну ок, спробуймо зліва!QHash<int, QByteArray> roles = !sourceModel()? {} : sourceModel()->roleNames();
А він у відповідь:
PaddingProxyModel.cpp:695:49: error: initializer list cannot be used on the right hand side of operator '?'
QHash<int, QByteArray> roles = !sourceModel()? {} : sourceModel()->roleNames();
^~
Короч, зліва теж не можна. Чого одразу не сказати щось на кшталт «не пиши initializer list в тернарніку»‽ Як у тому анекдоті про програмістів — максимально точна відповідь, яка, втім, не несе жодної користі.
❤2😁2
This media is not supported in your browser
VIEW IN TELEGRAM
Зацініть мою знахідку: черговий клієнт для #Git — debase!
Цього разу це не просто #CLI чи прога з ненависним графічним інтерфейсом. Цього разу це #TUI, тож взяли все ваше найулюбленіше з обох підходів: неможливість показувати нормальну деталізовану графіку + необхідність користуватися мишкою🤡 План надійний, як швейцарський годинник.
Втім виглядає симпатично )
Цього разу це не просто #CLI чи прога з ненависним графічним інтерфейсом. Цього разу це #TUI, тож взяли все ваше найулюбленіше з обох підходів: неможливість показувати нормальну деталізовану графіку + необхідність користуватися мишкою
Втім виглядає симпатично )
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6😁6🥰1
This media is not supported in your browser
VIEW IN TELEGRAM
Ну добре, а тепер вже без жартів корисна #TUI-прога, яку я років пʼять назад знайшов — pgcli. Це REPL для Postgres з автодоповненням та табличками.
З цікавого: виявилося, що основна розробниця — родом з Харкова!
А взагалі ця прога є частиною більшої організації, в якій є подібні #тулзи під різні бази даних: https://www.dbcli.com.
До речі хороших і при цьому безплатних GUI-аналогів я може і не знаю навіть. Якщо вам спадає щось на думку, закидайте мене посиланнями, плз.
З цікавого: виявилося, що основна розробниця — родом з Харкова!
А взагалі ця прога є частиною більшої організації, в якій є подібні #тулзи під різні бази даних: https://www.dbcli.com.
До речі хороших і при цьому безплатних GUI-аналогів я може і не знаю навіть. Якщо вам спадає щось на думку, закидайте мене посиланнями, плз.
🔥11👍4
Cіпласпластик
Окей, трохи навчив Perplexity зʼясовувати походження та звʼязки виконавців. Потестив на якихось назвах, що знайшов у #Spotify — не вгадало тільки CHAINY. (ДахаБраха та Ragapop — це 🇺🇦 звісно, а Paul Sabin ніби хвранцуз). Цікаво, що на цій задачі Claude 3…
Лишу це тут без зайвих коментарів https://stopru.in.ua/ (хоча у мене особисто проблеми з ютубом як раз немає на відміну від спотіфая)
stopRU
stopRU - дерусифікатор YouTube
Розширення для браузера, яке допоможе вам натренувати Youtube не рекомендувати російські відео.
❤6🔥1
Cіпласпластик
Отож про що це я? А, ну так, про дизайн-ревʼю та про код-ревʼю. Річ у тім, що у нас в компанії є шаблон для презентацій. Це, можна сказати, такий собі style guide, як у програмістів для коду. І в цьому шаблоні шрифт доволі маленький, а я у своїх слайдах…
До речі щодо ютубу. Готуючи свою презентацію, я покладався зокрема на ось цю чудову лекцію від професора Патріка Вінстона з MIT (який на жаль помер пʼять років тому, як я щойно дізнався 😢 ). Дивовижний приклад того, як чувак, розмовляючи доволі помірно й тихо, все одно зумів захопити мою увагу на цілу годину (хоча зазвичай у мене вже за пʼять хвилин починає дупа зудіти від нудьги). Я це відео вже двічі дивився навіть.
Зокрема, його рекомендації з оформлення слайдів для доповіді мені здалися вельми логічними, тож я їх прийняв для себе також, про що вже згадував раніше.
Зокрема, його рекомендації з оформлення слайдів для доповіді мені здалися вельми логічними, тож я їх прийняв для себе також, про що вже згадував раніше.
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
How to Speak
MIT How to Speak, IAP 2018
Instructor: Patrick Winston
View the complete course: https://ocw.mit.edu/how_to_speak
Patrick Winston's How to Speak talk has been an MIT tradition for over 40 years. Offered every January, the talk is intended to improve your…
Instructor: Patrick Winston
View the complete course: https://ocw.mit.edu/how_to_speak
Patrick Winston's How to Speak talk has been an MIT tradition for over 40 years. Offered every January, the talk is intended to improve your…
👍5
Натрапив на вправи для вивчення #Zig, в яких треба фіксити поламаний код. Доволі цікавий підхід для знайомства з мовою.
Codeberg.org
exercises
Learn the ⚡Zig programming language by fixing tiny broken programs.
❤6👍3
Я не фанат, але на сьогоднішній конфі Xbox (яка була найпотужнішою за весь Summer Game Fest) показали трейлер S.T.A.L.K.E.R. 2 українською! 🫶 Дякую GSC Game World за те, що це зробили, та Microsoft за те, що підтримали.
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
S.T.A.L.K.E.R. 2: Heart of Chornobyl — The Time of Opportunities Trailer - Xbox Games Showcase 2024
The Zone is what you consider it to be. I've shown you how I see it. Walk your own path, and you will come to perceive the Zone in your own way.
Featuring a huge, borderless open-world and a non-linear story, S.T.A.L.K.E.R. 2: Heart of Chornobyl releases…
Featuring a huge, borderless open-world and a non-linear story, S.T.A.L.K.E.R. 2: Heart of Chornobyl releases…
❤🔥9❤5
Як і очікувалося, електричний скутер #Honda Motocompacto, про який я вже писав, виявився вельми сумнівним.
Але цей допис — скоріш рекомендація каналу FortNine, які роблять дуже якісні в плані постановки відео на тему мотоциклів та деякі суміжні. Гляньте, доки робочий тиждень тільки-но розпочинається )
Але цей допис — скоріш рекомендація каналу FortNine, які роблять дуже якісні в плані постановки відео на тему мотоциклів та деякі суміжні. Гляньте, доки робочий тиждень тільки-но розпочинається )
YouTube
$1000 Honda Suitcase - Motocompacto Review
Rent a motorcycle affordably on your travels or make passive income renting yours out through Riders Share : https://www.riders-share.com/welcome/fortnine
A suitcase with wheels? Well, Honda has been there and done that in the 80s with the Motocompo, but…
A suitcase with wheels? Well, Honda has been there and done that in the 80s with the Motocompo, but…
👀1🦄1
Трохи про доведення справ до кінця.
Я вже якось згадував, що покладаюся на три тести для оцінки себе. Про один (від компанії Рея Даліо) я написав ще тоді, а зараз зʼявився привід згадати ще один: 16personalities. Насправді це безплатна і трохи простіша версія тесту Маєрс-Бріґс (на який Рей Даліо теж посилався), розробленого дочкою-психологинею та її матірʼю під натхненням від книги Карла Юнґа «Психологічні типи».
Тест дає на диво точні результати, але мова не про те. Я проходив його тричі: у 2018, 2020 та 2023. І перші два рази отримував INTP-A профіль, який вони називають Assertive Logician. А ось останній раз показники незначним чином змінилися, і я «став» ISTP-A, або Assertive Virtuoso. Головна зміна відбулася в другому параметрі, як можна побачити по літерах, тобто на шкалі від N (iNtuition) до S (obServation or Sensing). У 2018 я начебто покладався на інтуїцію на 67%, у 2020 — лише на 52%, а у 2023 всього на 48% (тобто тепер став на 52% спостережливим🧐 ).
Все це схоже на маячню, проте я зауважив, що приблизно в той самий час я став доводити до кінця деякі свої ініціативи: почав і дописав невеличку бібліотеку для QML разом з детальною документацією, якісь там модулі десь, трохи поконтрібʼютив в опенсорс… та навіть полички в хаті понавішував!
А днями трапився відос, де чувак проводить паралель між тим, як ми граємо в ігри та як робимо все інше в житті, на що його своєю чергою наштовхнула фраза з «Джона Віка», що звучить як
Поміркувавши, я зрозумів, що мій підхід до ігор завжди був приблизно такий: раз в ніколи я сідаю за компʼютерну гру, граю в неї майже цілодобово, і десь годин за 30–35 мене відвертає. Тож якщо гра коротка, я її встигаю пройти, а якщо ні, то просто кидаю. Цікаво, що свої пет-проєкти я зазвичай робив так само!
Аналізуючи далі, я збагнув, що схожий підхід у мене був також в універі: я цілий семестр розслаблявся, а потім рвав дупу, щоб закрити сесію за пару тижнів. (Я гроші не платив, тож окремим челенджем завжди було домовитися з викладачем про хоча б дозвіл на те, щоб здати всі лаби, практичні завдання тощо).
Але так було не завжди. Ще раніше я вчився у коледжі, а до того у школі. У мене завжди була гарна памʼять і швидкий мозок, тож я не мав значних складнощів з програмою навчання. Відмінність же була у тому, що я вчився регулярніше і більш поступово. Але в якийсь момент став покладатися на швидку памʼять занадто сильно.
Back to present day. Я пройшов свою нині улюблену гру Mass Effect (200 годин), я пройшов Baldur's Gate 3 (300 годин), у мене є як робочі, так і особисті ініціативи та проєкти, які хоч і неквапливо, але все ж просуваються впродовж доволі тривалого часу. Всі ці штуки поєднує той факт, що я більше не намагаюся подолати їх ривком — натомість я спокійно планую, а потім крок за кроком виконую.
Якщо я вам просто скажу: «start small, stay consistent» — це не допоможе. Тобто звісно саме так робити і треба, але… як себе змусити?
Моїми найголовнішими блокерами були: 1) відсутність відчуття, коли вже час спинитися (щоб не набридло завчасно) та 2) нездатність змусити себе зробити ще одну ітерацію (бо вже встигло остогиднути на попередній). Іншим аспектом була деяка моя ідеалістичність, яка сильно заважала, але на щастя поволі перетворюється на прагматичність, про що свідчить згаданий вище тест. Ну і ще купа чого.
Отож, підсумки не підбиваю. Кидайте свої результати тестів у коментарі.
Я вже якось згадував, що покладаюся на три тести для оцінки себе. Про один (від компанії Рея Даліо) я написав ще тоді, а зараз зʼявився привід згадати ще один: 16personalities. Насправді це безплатна і трохи простіша версія тесту Маєрс-Бріґс (на який Рей Даліо теж посилався), розробленого дочкою-психологинею та її матірʼю під натхненням від книги Карла Юнґа «Психологічні типи».
Тест дає на диво точні результати, але мова не про те. Я проходив його тричі: у 2018, 2020 та 2023. І перші два рази отримував INTP-A профіль, який вони називають Assertive Logician. А ось останній раз показники незначним чином змінилися, і я «став» ISTP-A, або Assertive Virtuoso. Головна зміна відбулася в другому параметрі, як можна побачити по літерах, тобто на шкалі від N (iNtuition) до S (obServation or Sensing). У 2018 я начебто покладався на інтуїцію на 67%, у 2020 — лише на 52%, а у 2023 всього на 48% (тобто тепер став на 52% спостережливим
Все це схоже на маячню, проте я зауважив, що приблизно в той самий час я став доводити до кінця деякі свої ініціативи: почав і дописав невеличку бібліотеку для QML разом з детальною документацією, якісь там модулі десь, трохи поконтрібʼютив в опенсорс… та навіть полички в хаті понавішував!
А днями трапився відос, де чувак проводить паралель між тим, як ми граємо в ігри та як робимо все інше в житті, на що його своєю чергою наштовхнула фраза з «Джона Віка», що звучить як
«How you do anything is how you do everything»(сама фраза походить чи то з дзен-буддизму, чи хтозна-звідки ще).
Поміркувавши, я зрозумів, що мій підхід до ігор завжди був приблизно такий: раз в ніколи я сідаю за компʼютерну гру, граю в неї майже цілодобово, і десь годин за 30–35 мене відвертає. Тож якщо гра коротка, я її встигаю пройти, а якщо ні, то просто кидаю. Цікаво, що свої пет-проєкти я зазвичай робив так само!
Аналізуючи далі, я збагнув, що схожий підхід у мене був також в універі: я цілий семестр розслаблявся, а потім рвав дупу, щоб закрити сесію за пару тижнів. (Я гроші не платив, тож окремим челенджем завжди було домовитися з викладачем про хоча б дозвіл на те, щоб здати всі лаби, практичні завдання тощо).
Але так було не завжди. Ще раніше я вчився у коледжі, а до того у школі. У мене завжди була гарна памʼять і швидкий мозок, тож я не мав значних складнощів з програмою навчання. Відмінність же була у тому, що я вчився регулярніше і більш поступово. Але в якийсь момент став покладатися на швидку памʼять занадто сильно.
Back to present day. Я пройшов свою нині улюблену гру Mass Effect (200 годин), я пройшов Baldur's Gate 3 (300 годин), у мене є як робочі, так і особисті ініціативи та проєкти, які хоч і неквапливо, але все ж просуваються впродовж доволі тривалого часу. Всі ці штуки поєднує той факт, що я більше не намагаюся подолати їх ривком — натомість я спокійно планую, а потім крок за кроком виконую.
Якщо я вам просто скажу: «start small, stay consistent» — це не допоможе. Тобто звісно саме так робити і треба, але… як себе змусити?
Моїми найголовнішими блокерами були: 1) відсутність відчуття, коли вже час спинитися (щоб не набридло завчасно) та 2) нездатність змусити себе зробити ще одну ітерацію (бо вже встигло остогиднути на попередній). Іншим аспектом була деяка моя ідеалістичність, яка сильно заважала, але на щастя поволі перетворюється на прагматичність, про що свідчить згаданий вище тест. Ну і ще купа чого.
Отож, підсумки не підбиваю. Кидайте свої результати тестів у коментарі.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥2👀1
Є у мене в домашній мережі купа self-hosted сервісів, значить. Більшість у докері. А проблема з докером у тому, що він порти на хостовій машині займає, так їх ще й памʼятати треба (або записувати кудись). І якось не прикольно потім у браузері писати та бачити
Як сервер у мене Synology NAS наразі, і там є вбудований реверс-проксі. Цього було б достатньо, щоб зробити собі адреси виду
Виявилося, що замість повноцінного DNS-сервера в локальній мережі можна використовувати mDNS, проте, з ним також є певні проблеми. А для більш-менш автоматичного налаштування реверс-проксі можна було б перейти на Træfik чи Caddy. Та це вже якось вище мого порога заморочливості.
Тож я здався та спробував Tailscale. Це така штука, яка дозволяє дуже легко та швидко побудувати свою VPN.
Ідея звісно не нова: ще на початку 2000-х ми з друганами думали, як нам грати разом в ігри, якщо ми живемо в різних районах. У першому StarCraft можна було, наприклад, зателефонувати модемом напряму модему другана, прикиньте☎️ Але то поодинокий випадок скоріш. А ось десь у 2004-му зʼявилася така славнозвісна в ті часи прога як Hamachi (на скріншоті саме вона). Вона дозволяла змусити ігри думати, що два віддалених компи насправді в одній локалці — те що треба!
Зараз такі штуки теж існують. Наприклад, ZeroTier. Ми з ексколегою намагалися через нього пограти віддалено в Cuphead, але воно зрідка давало неприємний лаг. (Ми з ним пограли врешті, але інакше).
Так ось, а шо Tailscale? Ну більшість з вас, мабуть, вже й так в курсі — це тільки я слоупок. Але фактично це те саме, тільки на базі (дуже швидкого) протоколу WireGuard, й до того ж підтримує меш-мережу.
Цікаве тут інше: tailscale можна підіймати прямо в докер-контейнері, фактично додаючи його у вашу мережу як окрему машину. Тобто виходить наче у вас є окремий комп, на якому стоїть тільки той сервіс, який ви там підняли. Отож з суботи я займався міграцією деяких штук у свій новий tailnet.
В принципі, процес доволі straight-forward. Налаштував собі простий GitOps для автоматичного деплоя ACLs та
Але зʼявилася зворотна проблема: не всі сервіси легко підіймаються на 80-му порту😤 Це тому, що перші 1024 порти привілейовані, й вішатись на них можуть тільки проги з відповідними правами. Однією з неспроможних штук виявився форк Gitea — Forgejo, який я вирішив собі підняти замість GitLab (бо останній заважкий для моїх потреб). Танцював навколо нього майже дві доби, але так і не зміг змусити його забайндити на себе 80-й порт. Зрештою довелося в контейнері ще підіймати nginx чисто заради цього.
Запрацювало тепер-то! Можу відкривати😎 (причому навіть не вдома, бо у мене навіть на телефоні Tailscale).
Цікаво до речі, що сучасні програми вкрай кепсько реагують на подібні короткі адреси: телеграм не запарсив як URL (з міркувань безпеки, я думаю), браузери постійно намагаються відкрити мені пошук замість сайту, а Arc навіть не зміг зберегти закладку🤡 Я не кажу вже про http (без s). Але це вже інша історія.
http://myserver:53412
. Як сервер у мене Synology NAS наразі, і там є вбудований реверс-проксі. Цього було б достатньо, щоб зробити собі адреси виду
http://myserver/gitlab
, але хочеться радше http://gitlab.mynetwork
. Тож підняв я додатково DNS-сервер (також від Synology, хоча там, мабуть, тільки юайка їхня) і зрозумів, що це дуже прям запарно налаштовувати тепер. Доводиться в декількох місцях одне й те саме прописувати.Виявилося, що замість повноцінного DNS-сервера в локальній мережі можна використовувати mDNS, проте, з ним також є певні проблеми. А для більш-менш автоматичного налаштування реверс-проксі можна було б перейти на Træfik чи Caddy. Та це вже якось вище мого порога заморочливості.
Тож я здався та спробував Tailscale. Це така штука, яка дозволяє дуже легко та швидко побудувати свою VPN.
Ідея звісно не нова: ще на початку 2000-х ми з друганами думали, як нам грати разом в ігри, якщо ми живемо в різних районах. У першому StarCraft можна було, наприклад, зателефонувати модемом напряму модему другана, прикиньте
Зараз такі штуки теж існують. Наприклад, ZeroTier. Ми з ексколегою намагалися через нього пограти віддалено в Cuphead, але воно зрідка давало неприємний лаг. (Ми з ним пограли врешті, але інакше).
Так ось, а шо Tailscale? Ну більшість з вас, мабуть, вже й так в курсі — це тільки я слоупок. Але фактично це те саме, тільки на базі (дуже швидкого) протоколу WireGuard, й до того ж підтримує меш-мережу.
Цікаве тут інше: tailscale можна підіймати прямо в докер-контейнері, фактично додаючи його у вашу мережу як окрему машину. Тобто виходить наче у вас є окремий комп, на якому стоїть тільки той сервіс, який ви там підняли. Отож з суботи я займався міграцією деяких штук у свій новий tailnet.
В принципі, процес доволі straight-forward. Налаштував собі простий GitOps для автоматичного деплоя ACLs та
docker-compose.yaml
файлів. Наче норм.Але зʼявилася зворотна проблема: не всі сервіси легко підіймаються на 80-му порту
Запрацювало тепер-то! Можу відкривати
http://git/
та насолоджуватися Цікаво до речі, що сучасні програми вкрай кепсько реагують на подібні короткі адреси: телеграм не запарсив як URL (з міркувань безпеки, я думаю), браузери постійно намагаються відкрити мені пошук замість сайту, а Arc навіть не зміг зберегти закладку
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥2🤯2👀1 1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8🤝2👀1
Як же складно (і прикольно) мати свій домашній сервачок, жах!
В принципі Tailscale справді дещо спростив. Але пару додаткових днів я все-таки вбив: то зовнішні адреси не пінгуються, а тільки адреси з tailnet, то навпаки, то і ті, й інші відвалилися, то на хостовій системі ок, а в контейнері адреси не резолвляться, то контейнери з
Tailscale зручний, та все ж далекий від ідеалу. Наприклад, на macOS у них аж три різні офіційно підтримувані версії з різним набором фічей, а на моєму Synology він працює з низкою обмежень. (До речі в обох випадках головна завада — системний сендбоксинг). Одначе користуватися цим можна.
Єдине, що не подобається — залежність від їхнього сервера. Він виконує тільки адміністративно-координаційну роботу на щастя, і все ж!
У попередньому дописі я згадував Tailscale мого дитинства — Hamachi. І знаєте, що з ним трапилося? Він перетворився на лайно💩 Сталося це в ту мить, коли його купила угорська компанія 3am Labs, яка згодом стала називатися LogMeIn, яка до речі пізніше купила й LastPass, а ще пізніше злилася з дочірньою компанією Citrix, що робила GoToMeeting та інші продукти з тієї ж серії, тож зараз вона так і називається — GoTo. Якщо ви колись користувалися LastPass (у яких вже регулярно крадуть користувацькі дані), «новим» Hamachi або GoTo Meeting, то нескладно помітити коричневу марку якості.
Як же себе захистити від подібного з Tailscale? Ну, на щастя їхній демон та CLI-клієнт — повністю open-source. Сервер ні, проте, вони не забороняють використовувати якийсь свій, тож це було питанням часу, коли хтось напише власний. Чекати довго не знадобилося: наразі існує доволі фічастий Headscale. Тож виходить, що в принципі можна все потрібне заселфхостити.
Що саме Tailscale дає особисто мені? Ну, декілька речей:
• легке налаштування віддаленого доступу до якихось селф-хостед речей без необхідності випускати їх в публічний інтернет. Тобто не треба прокидати порти кудись назовні, морочити голову з DNS або DDNS тощо, а потім трястися, що хтось підбере твій qwerty123. У мене серед таких речей мій ґіт-сервак, книжки, скани документів, база хавки, Home-Assistant і т.д.
• легша взаємодія зовнішніх сервісів (low-code платформи для автоматизації або тих же GitHub Actions) з цими внутрішніми штуками. Робиться це завдяки ефемерним ключам, наприклад: у вас на раннері запускається пайплайн, авторизується в tailnet (з відповідними правами), спілкується з потрібною нодою, а потім видаляється з мережі щойно йде офлайн (в кінці workflow).
• швидке перекидання файлів між пристроями а ля AirDrop.
Поки це всі юзкейси, може згодом ще щось знайду. А зараз відчуваю, що досить — моя devops-чаша вже переповнена ))
В принципі Tailscale справді дещо спростив. Але пару додаткових днів я все-таки вбив: то зовнішні адреси не пінгуються, а тільки адреси з tailnet, то навпаки, то і ті, й інші відвалилися, то на хостовій системі ок, а в контейнері адреси не резолвляться, то контейнери з
restart: always
не рестартують (до речі хз чого). Ну а зрештою взагалі випадково вбив свій інстанс ґітлабу, тому що запустив два контейнери, обидва з яких писали в одну теку.Tailscale зручний, та все ж далекий від ідеалу. Наприклад, на macOS у них аж три різні офіційно підтримувані версії з різним набором фічей, а на моєму Synology він працює з низкою обмежень. (До речі в обох випадках головна завада — системний сендбоксинг). Одначе користуватися цим можна.
Єдине, що не подобається — залежність від їхнього сервера. Він виконує тільки адміністративно-координаційну роботу на щастя, і все ж!
У попередньому дописі я згадував Tailscale мого дитинства — Hamachi. І знаєте, що з ним трапилося? Він перетворився на лайно
Як же себе захистити від подібного з Tailscale? Ну, на щастя їхній демон та CLI-клієнт — повністю open-source. Сервер ні, проте, вони не забороняють використовувати якийсь свій, тож це було питанням часу, коли хтось напише власний. Чекати довго не знадобилося: наразі існує доволі фічастий Headscale. Тож виходить, що в принципі можна все потрібне заселфхостити.
Що саме Tailscale дає особисто мені? Ну, декілька речей:
• легке налаштування віддаленого доступу до якихось селф-хостед речей без необхідності випускати їх в публічний інтернет. Тобто не треба прокидати порти кудись назовні, морочити голову з DNS або DDNS тощо, а потім трястися, що хтось підбере твій qwerty123. У мене серед таких речей мій ґіт-сервак, книжки, скани документів, база хавки, Home-Assistant і т.д.
• легша взаємодія зовнішніх сервісів (low-code платформи для автоматизації або тих же GitHub Actions) з цими внутрішніми штуками. Робиться це завдяки ефемерним ключам, наприклад: у вас на раннері запускається пайплайн, авторизується в tailnet (з відповідними правами), спілкується з потрібною нодою, а потім видаляється з мережі щойно йде офлайн (в кінці workflow).
• швидке перекидання файлів між пристроями а ля AirDrop.
Поки це всі юзкейси, може згодом ще щось знайду. А зараз відчуваю, що досить — моя devops-чаша вже переповнена ))
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - tailscale/tailscale: The easiest, most secure way to use WireGuard and 2FA.
The easiest, most secure way to use WireGuard and 2FA. - tailscale/tailscale
❤3👍1👀1
Media is too big
VIEW IN TELEGRAM
Кому взагалі здалося хорошою ідеєю робити stretch для зображень? Хіба це має сенс бодай колись? Фігачнув собі “Arc Boost” (нормальні люди називають це UserCSS) для нещодавно встановленого Calibre-Web, бо не було сил терпіти це.
Код виглядає отак:
Моє знання CSS наближається до 0, тож я попросив ШІ-шку це зробити (Claude 3.5 Sonnet норм), а потім перебором додавав
Не знаю, як вам, а мені обкладинки трохи різних розмірів муляють око значно менше, ніж розтягнуте зображення.
Втім загалом враження від Calibre-Web радше негативне. Це зовсім не «plex для книжок», як я розраховував. Найбільше мені сподобалося, коли я натиснув кнопку, щоб стягнути для книги метадані з інтернету, воно наче щось знайшло, перемістило файл в іншу теку, а БД чогось оновити не змогло, і просто роллбекнуло транзакцію 🤷🏻♂️ Тож база розійшлася з файлухою у перші ж 20 хвилин користування ))
Це мені нагадує два кардинально різних підходи до збереження просканованих документів. Paperless-ngx мейнтейнить базу з лінками на файлову систему, причому вміє розкладати за схемою, яку ви самі встановлюєте. А автор Docspell каже:
— тож він просто складає все у Postgres. І капе-е-е-ець, з одного боку звучить логічно, а з іншого боку — ну дуже лячно!😬 Бо якщо база якось покораптилася, то у першому випадку хоча б файли лишаються, а у другому — скоріш за все «це кінець». Ви як би робили, якби оригіналів документів у вас не лишилося?
Код виглядає отак:
.container-fluid .book .cover span img {
height: unset !important;
max-height: 100%;
position: absolute !important;
bottom: 0;
}
Моє знання CSS наближається до 0, тож я попросив ШІ-шку це зробити (Claude 3.5 Sonnet норм), а потім перебором додавав
!important
, доки воно не запрацювало. Не знаю, як вам, а мені обкладинки трохи різних розмірів муляють око значно менше, ніж розтягнуте зображення.
Втім загалом враження від Calibre-Web радше негативне. Це зовсім не «plex для книжок», як я розраховував. Найбільше мені сподобалося, коли я натиснув кнопку, щоб стягнути для книги метадані з інтернету, воно наче щось знайшло, перемістило файл в іншу теку, а БД чогось оновити не змогло, і просто роллбекнуло транзакцію 🤷🏻♂️ Тож база розійшлася з файлухою у перші ж 20 хвилин користування ))
Це мені нагадує два кардинально різних підходи до збереження просканованих документів. Paperless-ngx мейнтейнить базу з лінками на файлову систему, причому вміє розкладати за схемою, яку ви самі встановлюєте. А автор Docspell каже:
«Якщо у вас є окремо база та окремо файли, то це питання часу, коли трапиться розсинхрон»
— тож він просто складає все у Postgres. І капе-е-е-ець, з одного боку звучить логічно, а з іншого боку — ну дуже лячно!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👀1
В #UX найстрашніший гріх — це втрата користувацьких даних. Але коли про це кажеш, то люди зазвичай одразу уявляють, як їхні світлини в клауді зникли, або орендований сервер вмер без бекапу, або паролі десь протекли та таке інше.
Проте ні, правило максимально просте:
Ну тобто мова про збереження стану загалом, так. Щоразу, як вас змушують повторно заповнювати форму, знов скролити до місця, на якому ви припинили читати, або навіть просто знов логінитися — це кепський UX.
Але найбільше мене тіпає, коли ти вводиш якийсь текст, а програма його після певних дій втрачає🤬 Повна зневага до часу користувача та до виконаної ним роботи.
Історично так склалося, що вкрай погано з цим саме у вебі, бо там для збереження стану треба докладати окремих зусиль. Памʼятаю, як 20 років тому сформував звичку копіювати текст повідомлення (особливо довгого) перед надсиланням — досі так роблю, і ще жодного разу не пошкодував навіть в теперішні часи.
Але чого я зовсім не розумію, так це отаких приколів, як у відосі: контрол втрачає фокус, якщо при селекшні курсор миші опиняється за його межами, а на втрату фокуса він кенселяє операцію. У мене звичка все селектити, тож я від цього страждаю, причому значно частіше, ніж можна було б уявити: на кожному третьому сайті така хєрня. Підозрюю, що це поведінка з якогось всратого UI-фреймворка для вебу.
Просто не передавайте фокус в інший контрол на release event, м? Робіть це тільки на press. Як вам така ідея?
Проте ні, правило максимально просте:
Якщо користувач щось зробив, програма мусить це запамʼятати.
Ну тобто мова про збереження стану загалом, так. Щоразу, як вас змушують повторно заповнювати форму, знов скролити до місця, на якому ви припинили читати, або навіть просто знов логінитися — це кепський UX.
Але найбільше мене тіпає, коли ти вводиш якийсь текст, а програма його після певних дій втрачає
Історично так склалося, що вкрай погано з цим саме у вебі, бо там для збереження стану треба докладати окремих зусиль. Памʼятаю, як 20 років тому сформував звичку копіювати текст повідомлення (особливо довгого) перед надсиланням — досі так роблю, і ще жодного разу не пошкодував навіть в теперішні часи.
Але чого я зовсім не розумію, так це отаких приколів, як у відосі: контрол втрачає фокус, якщо при селекшні курсор миші опиняється за його межами, а на втрату фокуса він кенселяє операцію. У мене звичка все селектити, тож я від цього страждаю, причому значно частіше, ніж можна було б уявити: на кожному третьому сайті така хєрня. Підозрюю, що це поведінка з якогось всратого UI-фреймворка для вебу.
Просто не передавайте фокус в інший контрол на release event, м? Робіть це тільки на press. Як вам така ідея?
This media is not supported in your browser
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
💯7👍2🤬2😢1
Принаймні я б може так і робив, але у мене є #1Password. Я багато якими аналогами користувався, але щойно спробував його — одразу оформив передплату. Зараз розповім чому, бо, схоже, далеко не всі розуміють можливості.
По-перше, він тупо зручніший. У мене був KeePass, LastPass, Dashlane, може ще щось… та навіть хвалений Bitwarden — це все якнайменше на голову нижче за 1Password. Не знаю, чому вони можуть, а інші ні, проте, це відчутно прям сильно. Тільки у браузері на андроїді бувають проблеми — там Chrome час від часу починає свій вбудований зберігач паролів парити та відмовляється натомість пропонувати обраний вами.
В принципі гарного #UX для мене вже є достатнім приводом для передплати. Та ці чуваки добре розуміють свій продукт: він обростає новими фічами, які при цьому не безглузді. Отож…
По-друге! Він дозволяє зберігати SSH-ключі прямо в собі — вони у мене на файловій системі навіть не лежать. Просто прописуєте у свій
і ваш SSH-клієнт почне ходити за ключем прямо у 1Password, запитуючи біометрику за потреби.
По-третє, мені завжди було ліньки розбиратися з GPG. Але нині можна підписувати свої коміти SSH-ключем. Принаймні GitHub та GitLab це розуміють (Gitea/Forgejo наче поки що ні, та це питання часу). Налаштовується ізічно через
Окрім того, він має власну CLI-прогу, а це відчиняє нові двері. Наприклад, можна використовувати паролі/токени/ключі у різних скриптах та не перейматися, що воно лишиться в історії у відкритому вигляді:
У 1Password можна створювати декілька сховищ (vaults). Так у мене є особисте, робоче, шарене з дружиною та, наприклад, сховище для одного з серверів. А торік вони додали можливість створювати додаткові сервісні облікові записи — спецом для інтеграції в різноманітні пайплайни.
Тож тепер своїми secrets можна керувати прямо у 1Password, а не на умовному ґітгабі. А потім використовувати їхню готову дію для GitHub Actions. Не знаю, наскільки це гірше чи краще за використання якогось HashiCorp Vault, але для моїх аматорських потреб цього з головою.
Ще я в Ansible прямо з нього креденшиалзи свої дістаю в
Або прямо в плейбуці, щоб залогуватися в умовний Tailscale той самий чи в апішку ґітгаба:
Там ще багато чого є, як от підтримка passkeys, провайдер для Pulumi, вебхук для k8s тощо. А якщо ви маєте якийсь опенсорс-проєкт, то можна взагалі отримати team-акаунт задарма.
Короч, знаю, це виглядає як реклама, та це той інструмент, котрий я щиро рекомендую.
По-перше, він тупо зручніший. У мене був KeePass, LastPass, Dashlane, може ще щось… та навіть хвалений Bitwarden — це все якнайменше на голову нижче за 1Password. Не знаю, чому вони можуть, а інші ні, проте, це відчутно прям сильно. Тільки у браузері на андроїді бувають проблеми — там Chrome час від часу починає свій вбудований зберігач паролів парити та відмовляється натомість пропонувати обраний вами.
В принципі гарного #UX для мене вже є достатнім приводом для передплати. Та ці чуваки добре розуміють свій продукт: він обростає новими фічами, які при цьому не безглузді. Отож…
По-друге! Він дозволяє зберігати SSH-ключі прямо в собі — вони у мене на файловій системі навіть не лежать. Просто прописуєте у свій
~/.ssh/config
отаке:Host *
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
і ваш SSH-клієнт почне ходити за ключем прямо у 1Password, запитуючи біометрику за потреби.
По-третє, мені завжди було ліньки розбиратися з GPG. Але нині можна підписувати свої коміти SSH-ключем. Принаймні GitHub та GitLab це розуміють (Gitea/Forgejo наче поки що ні, та це питання часу). Налаштовується ізічно через
.gitconfig
:[gpg]
format = ssh
[gpg "ssh"]
program = /Applications/1Password.app/Contents/MacOS/op-ssh-sign
[commit]
gpgsign = true
Окрім того, він має власну CLI-прогу, а це відчиняє нові двері. Наприклад, можна використовувати паролі/токени/ключі у різних скриптах та не перейматися, що воно лишиться в історії у відкритому вигляді:
yt-dlp <link> --password (op read op://Personal/SomeWebsite/password)
У 1Password можна створювати декілька сховищ (vaults). Так у мене є особисте, робоче, шарене з дружиною та, наприклад, сховище для одного з серверів. А торік вони додали можливість створювати додаткові сервісні облікові записи — спецом для інтеграції в різноманітні пайплайни.
Тож тепер своїми secrets можна керувати прямо у 1Password, а не на умовному ґітгабі. А потім використовувати їхню готову дію для GitHub Actions. Не знаю, наскільки це гірше чи краще за використання якогось HashiCorp Vault, але для моїх аматорських потреб цього з головою.
Ще я в Ansible прямо з нього креденшиалзи свої дістаю в
inventory.yml
типу такого:macmini_m1:
ansible_host: "{{ lookup('community.general.onepassword', 'Mac mini M1', vault='Server', field='url') }}"
ansible_user: "{{ lookup('community.general.onepassword', 'Mac mini M1', vault='Server', field='username') }}"
ansible_become_password: "{{ lookup('community.general.onepassword', 'Mac mini M1', vault='Server', field='password') }}"
Або прямо в плейбуці, щоб залогуватися в умовний Tailscale той самий чи в апішку ґітгаба:
Authorization: Bearer {{ lookup('community.general.onepassword', gh_api_token.item, **gh_api_token.args) }}
Там ще багато чого є, як от підтримка passkeys, провайдер для Pulumi, вебхук для k8s тощо. А якщо ви маєте якийсь опенсорс-проєкт, то можна взагалі отримати team-акаунт задарма.
Короч, знаю, це виглядає як реклама, та це той інструмент, котрий я щиро рекомендую.
👍14🔥3🤯2🥰1👀1
C++-комітет продовжує підглядати в спеку Haskell обговорювати нові потенційні фічі для мови. Цього разу (документу вже рік насправді) дійшло до плейсголдерів
Тут типу третє значення нам не суттєве, тож можна використати
Та C++ би не був собою, якби все було так прозоро. Ніщо не заважає вам і зараз використати
Тож це працюватиме й надалі. Однак інколи хочеться зробити так двічі в одному скоупі, а structured binding — це визначення нової змінної, а не просто запис у ту, що вже існує:
Зараз такий код генерує
Тобто можна навіть вручну скільки завгодно разів оголошувати змінну
В принципі, очевидно, еге ж?) А, до речі… У неймспейсі двічі не можна оголосити:
Все логічно, короч🤡 Ні, заждіть, це не жарт. Все справді логічно, якщо над цим поміркувати достатньо довго! Але капець, як же втомлює тримати подібні нюанси в голові весь час.
З іншого боку шанси, що це увійде в C++26, все одно низькі ) Може в C++32…
_
, щоб зручно було користуватися зіставленням із взірцем (паттерн-матчінгом), якого звісно досі нема, або, наприклад, розпаковувати кортежі на кшталт:auto [x, y, _] = f();
Тут типу третє значення нам не суттєве, тож можна використати
_
, щоб не вигадувати імʼя, а потім боротися з ворнінгами про те, що воно не використовується, додаючи [[maybe_unused]]
.Та C++ би не був собою, якби все було так прозоро. Ніщо не заважає вам і зараз використати
_
як імʼя змінної:auto [x, _] = make_pair(1, 2);
cout << x << "," << _ << endl; // використання
Тож це працюватиме й надалі. Однак інколи хочеться зробити так двічі в одному скоупі, а structured binding — це визначення нової змінної, а не просто запис у ту, що вже існує:
auto [x, _] = make_pair(1, 2);
auto [_, y] = make_pair(3, 4);
Зараз такий код генерує
error: conflicting declaration ‘auto _’
, бо це повторна декларація змінної, а от з новим пропоузалом перестане. Тобто можна навіть вручну скільки завгодно разів оголошувати змінну
_
, і жодних проблем… доти, доки не спробувати звернутися до змінної _
у цьому ж скоупі. Якщо вона оголошена один раз, то можна, а якщо декілька, то це помилка:auto _ = 42; // Оголошення
auto _ = 0; // Повторне оголошення
{
auto _ = 1; // Новий скоуп. Оголошення з шадовінгом
assert( _ == 1 ); // Можна прочитати
}
assert( _ == 42 ); // Не можна прочитати 🙂
В принципі, очевидно, еге ж?) А, до речі… У неймспейсі двічі не можна оголосити:
namespace a {
auto _ = f(); // Ок
auto _ = f(); // Помилка
}
Все логічно, короч
З іншого боку шанси, що це увійде в C++26, все одно низькі ) Може в C++32…
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1😁1👀1
Трапився на очі написаний на C++ та Dear ImGui hex-редактор ImHex. Низькорівневі штуки — то трохи не мій профіль, але днями як раз став у пригоді. Доволі непогано зроблений, мені сподобався. Є вбудована C-like мова для опису структури бінарного формату. Та навіть онлайн можна використовувати прямо у браузері.
👍5❤1👏1🤝1