Євгеній Гизила
378 subscribers
46 photos
1 file
89 links
Автор @hyzyla

Пишу про різне зі світу веб розробки: власний досвід, Python, React, TypeScript, стартапи і власні думки
Download Telegram
Please open Telegram to view this post
VIEW IN TELEGRAM
Ринок browser extensions

На днях натрапив на посилання, де автор безкоштовного розширення для браузерів Hover Zoom+ (400 тис. користувачів)
зібрав в одному місці всі листи, які йому приходили з пропозицією монетизувати чи продати розширення. Пропонують від 2k$ на місяць і до 1k$ в день пасивного доходу 💸. Знайшов також статті інших розробників, які діляться схожими історіями [1], [2]

Основні причини для чого купують розширення це:

- 🔍 збирати й перепродавати дані про вас: по яких сайтах ходите, які фотки лайкаєте, які магазини відвідували і т.д. В першу чергу для маркетингових цілей.
- ⚡️ вбудовувати рекламу на випадкових сайтах, навіть на тих на яких її не мало б бути.
- ⚖️ і найчорніше: викрадати акаунти чи робити якісь інші зловмисні дії від вашого імені.


Рішення чи висновків до цієї проблеми у мене немає. Продати чи монетизувати свою роботу це нормально, якщо вона не порушує ніяких законів. Але й розумію людей, які не хочуть платити за браузерні розширення 🤷
Please open Telegram to view this post
VIEW IN TELEGRAM
Вашій увазі коротка стаття (4 хв) з конкретними порадами як покращити славнозвісні soft skills в письмовій комунікації в команді. Ділюся з вами, бо в більшості згоден з усіма порадами в цій статті.

6 tiny wording tweaks to level up your communication as a software engineer
Forwarded from Навколо розробки (DN)
На днях Rust-ентузіасти у лиці команди Astral Software написали у своєму блозі про uv, черговий інструмент для екосистеми Python, написаний на Rust - https://astral.sh/blog/uv
Якщо коротко - прирости швидкості у визначенні та встановленні залежностей колосальні (від 7 до 115 разів!)
Як то водиться, поки що uv у стадії розробки, і для ваших важливих речей краще користуватися перевіреними рішеннями, в котрих фокус на стабільності та сумісності (я про умовний pip).
Але - у Astral Sofrware амбіційні цілі, роудмап та, начебто, непогано все поки виходить, тому можна стежити та (можливо) експериментувати в очікуванні нових версій uv та інших корисностей.
👆 До слова, підписуйтеся на канал @this_is_pythonic Дмитра , автора попереднього допису. Має гарний канал про Python і розробку в цілому
SweetPad

Хочу розказати про останній власний проєкт над яким працював. Це розширення для VSCode, щоб можна було робити iOS/Swift мобільні застосунки у VSCode. Робоча назва SweetPad. Дуже грубо така собі альтернатива Xcode (хоча Xcode має бути все одно встановлений). 

Ідея виникла, коли сам не зміг в Xcode і поліз шукати які є альтернативи. Виявилося, що я не один кому не сподобався Xcode і люди теж шукають які є інші варіанти.  

Поки моє розширення непогано справляється з простими проєктами: можна запустити симулятор, зібрати й запустити застосунок на симуляторі. Ще налаштував Format-On-Save через SwiftFormat. Але далі ще купа ідей, що можна додати у розширення.

https://github.com/sweetpad-dev/sweetpad

UPD: Якщо ви iOS розробник, то буду вдячний за зворотній звʼязок
["JS"].contains?

В JS є метод .includes(…), щоб перевірити чи є елемент у масиві:

const arr = ["I", "love", "Python"];

console.log(arr.includes("love"));
// true

console.log(arr.includes("js"));
// false


Працює як і очікуєш. Але чому цей метод називається не .contains(…)? Я, для прикладу, по інтуїції не раз починав писати саме contains, замість includes.

Відкопав старі обговорення, де спочатку більшість погодили назву "contains", для методу якийсь буде перевіряти чи є елемент у масиві і написали proposal до нової версії JS, ES7. Далі Firefox реалізував цей метод у себе, випустив нову версію і посипалися звернення від користувачів, що їхні сайти зламалися.

Зʼясувалося, що основною причиною є MooTools, бібліотека по типу jQuery. Ця бібліотека реалізовувала .contains самостійно, задовго до того як зʼявився цей proposal, і розширювала методи Array обʼєкту. Через різницю між реалізаціями, сайти, які використовували MooTools, почали ламатися.

Далі автори ES7 приймають рішення перейменувати .contains в .includes., бо на час MooTools використовували 6.5% сайтів і буде неправильно зламати їх. З часом MooTools перестав активно підтримуватися, але .includes тепер схоже з нами назавжди, а .contains залишився в історії 🫡
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from FEDOROV
Дія відкриває код

Відтепер країни, які цікавляться українським досвідом цифровізації, зможуть зрозуміти логіку Дії, імпортувати код і запустити власні державні сервіси. Сподіваюся, що наш досвід допоможе іншим урядам побудувати свої держави в смартфоні.

Фахівці зможуть створити аналог Дії або інший застосунок, схожий на неї, але для цього, звісно, треба буде приєднатися до публічної ліцензії. Знайти відкритий код та доєднатися до ліцензії можна на окремому сайті.

Першим кроком, окрім загального коду серверної й мобільної частини застосунку, ми додали документ Посвідчення водія та послугу Витяг про несудимість як приклади логіки роботи застосунку з даними. Із часом послуг та документів буде більше.

А ще кожен айті-фахівець зможе проаналізувати код і запропонувати, як покращити Дію.

Дані українців у повній безпеці. У коді немає доступу до реєстрів. Якщо айтівець захоче зробити «запит у реєстр», то спеціально для цього в тестове середовище завантажили видуманих користувачів із вигаданими даними. На цих користувачах можна перевірити логіку роботи з інформацією.

Відкритий код — це одна з топових світових практик. За таким підходом робили європейські ковід-сертифікати та Європейський гаманець цифрової ідентифікації, а також так працюють компанії Linux, Android та MySQL.

Ділимося українським діджитал-досвідом і зміцнюємо міжнародний імідж цифрової країни.
curl --json

Пропустив новину, що в curl додали новий параметр --json. Цей параметр буде проставляти правильні заголовки і використовувати POST як метод запиту. Раніше, щоб зробити запит з JSON тілом треба було самостійно прописувати заголовки, бо за замовчуванням Content-Type відправлявся як application/x-www-form-urlencoded

Дрібна зміна, але зручна ж!

1. Документація
2. Коміт
React SQL

Завтра сідаю писати custom react renderer для SQL запитів. Тільки уявіть, що SQL запити можна писати в зручному JSX форматі. А замість страшних CTE у вас pure React компоненти

Мінуси будуть? 😂
stdout buffer

Пишу розширення для VSCode і хочу запустити програму xcodebuild для збірки iOS проєкту. Сам xcodebuild працює досить довго і постійно друкує в stdout результат збірки. Тому мені треба дати зворотний зв'язок користувачу і постійно друкувати логи з xcodebuild в інтерфейсі VSCode.

VSCode розширення в мене написане на Node.js, тому в коді це виглядає приблизно так:

import { spawn } from ‘child_process’;

const child = spawn('xcodebuild’, […]);

child.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
// … далі виводимо в vscode
});


Запускаю це скрипт, але, по власних відчуттях, дані в stdout прилітають з якимись затримками, ніби є якась пауза між викликами функції, яка обробляє stdout. Я відразу ж подумав, що це якась проблема з node.js і поліз гуглити.

На мій подив, виявилося, що це стандартна поведінка всіх програм, які залежать від glibc і ця поведінка не залежить від того хто намагається зчитати stdout: чи то Node.js, чи то Python. Сам glibc обробляє вивід приблизно так: якщо програму запущено з термінала, то у stdout вивід буде потрапляти кожен раз, коли у буфер потрапляє символ нового рядка \n. В інших випадках вивід буде буферизуватися поки не назбирається достатня кількість символів. Часто розміру цього буферу 8 кб, тобто поки не назбирається 8 кб у буфері, то батьківський процес не зможе отримати дані з stdout.

В моєму випадку я запускаю xcodebuild не з термінала, а з VSCode, тому вивід програми віддається рівними шматками й саме тому виникає відчуття затримки, бо поки xcodebuild не надрукує близько десятки рядків, щоб наповнити буфер, node.js не отримає відповіді.

Як це обійти? Сама програма, яку викликають, в моєму випадку xcodebuild, може контролювати чи потрібно буферизувати вивід. Для прикладу, в Python є змінна оточення PYTHONUNBUFFERED, яка вимикає буферизацію для stdout. Інший популярний варіант це створити псевдотермінал (pty) і вже з нього запустити команду. Тоді в stdout дані будуть потрапляти після символу нового рядка. Але треба бути обережним з псевдотерміналом, бо тоді у вивід можуть потрапляти символи кольору і їх треба теж обробляти. Також треба задавати уявні розміри псевдотермінала, якщо програма враховує його розміри.

Я ж обійшов буферизацію для мого випадку через маленьку бібліотеку, яку підвантажую через змінну оточення LD_PRELOAD. Дивитися моє рішення тут 👀

Також залишу посилання на гарну статтю на цю тему stdio buffering
<meta name="viewport" />

Майже кожний сучасний вебсайт має такий тег в себе в голові:


<meta name="viewport" content="width=device-width, initial-scale=1" />


Недавно десь вичитав, що історія цього тегу йде від появи перших iPhone у 2007 році. Тоді купа сайтів у світі не вміло підлаштовуватись під розмір мобільного екрану і тому вебсайт за замовчуванням мав ширину 980 px і виглядав як на скріншоті вище. Сайт виглядав більш менш нормально, а користувач міг за потреби міг приблизити вебсайт 🔎

Якщо сайт умів підлаштовуватися під мобілку, то він міг виставити оцей meta тег у голові, який буде говорити браузеру: «так, можеш не прикидатися таким широким й рендерити на реальній ширині девайсу»
UPPER case

Цікавий факт, що слова uppercase і lowercase походять з друкарського ремесла. Раніше літери для верстата зберігалися в комірках футляра, який складався з двох частин. В цьому футлярі великі літери були у верхній половині, а малі у нижній. Тому дослівно виходить, що uppercase літера — це літера з верхньої частини футляра.
JSONB statistics

PostgreSQL Stories: From slow query to fast—via stats | Render Blog

Історія оптимізації простого запиту в PostgreSQL від компанії Render.

SELECT e.id
FROM events e
JOIN postgres_dbs db
ON e.data ->> 'serviceId' = db.database_id
LIMIT 1;


Таблиця events великих розмірів, postgres_dbs — відносно невелика. Є індекси і на db.database_id, і на e.data ->> 'serviceId'. Але JOIN працює довго.

В результаті автор прийшов до цікавого спостереження, що PostgreSQL не збирає статистику по полях в JSONB. Через це база має мало уявлення, що там може бути і тому погано планує запит 😱

Вирішується проблема створенням вручну статистики по полю JSONB (вперше почув про таку можливість):

CREATE STATISTICS events_service_id
ON (data ->> 'serviceId'::text)
from events;


Мені відразу ж захотілося піти передивитися всі запити, які якось шукають по JSONB. Ще по цій темі нарив ще таку статтю PostgreSQL - JSONB and Statistics
Пароль треба?

Поступово приходжу до думки, що часто вилогінювати користувача з сервісу це вже й не така гарна ідея для безпеки як я раніше думав. Якщо десь є про це гарні професійні обговорення, то дайте знати. Наведу три приклади з мого життя:

Користуюся Bitwarden як менеджер паролів. Так от він час від часу блокує сховище і просить ввести master пароль, щоб його розблокувати. От прям вчора сиджу у кавʼярні, а Bitwarden просить пароль і через біометрію не дає розблокувати. А що якщо камера спостереження пише відео й охоронець зможе відновити всі мої паролі? Ну і ця ж проблема не унікальна тільки для менеджера паролів, бо кажуть, що пошту найкраще перевіряти пошту в якійсь кавʼярні за макбуком. Ви купили каву, відкриваєте ноутбук, а у вас там сесія в Gmail закінчилася ☕️

Наступна історія теж повʼязана з менеджерами паролів. Не на всіх сайтах і не у всіх мобільних додатках мій менеджер паролів уміє підставляти пароль у форму. Тоді приходить копіювати цей пароль і вставляти вручну у поле для пароля. Звісно ж після копіювання цей пароль живе собі спокійно в буфері обміну. Декілька раз так забував про пароль у буфері обміну і вставив його кудись куди не треба, наприклад у поле для повідомлення у Slack чи десь у коді — "Г'юстоне, у нас там помилка xA9owEaQyPd@!k, ой, NoSuchKey" 💬

Третя історія про робочі інструменти. Я кожен день реагую на десятки сповіщень, які приходять на пошту і переходжу по посиланнях з цих листів. За моїми оцінками майже нуль шансів, що я помічу щось підозріле, якщо мені прислати фішинговий сайт з формою входу. Особливо якщо справжній сервіс й так по пару раз на тиждень мене питає пароль. З чого б мені щось запідозрити? 🫣

Зрозуміло, що у вас таких проблем немає і частину проблем якось можна вирішити. Але я за собою помічаю, що чим частіше мені треба ввести пароль, то я тим більше я втрачаю пильність і тим ймовірніше я цей пароль десь засвічу 🔐
Please open Telegram to view this post
VIEW IN TELEGRAM
Я сильно довго прокрастинував написати про своє розширення для iOS/Swift розробки на Reddit. Напевно це все через страх бути розкритикованим. Але по факту досить непогано моє розширення сприйняли в середовищі iOS розробників на Reddit. За день +40 зірочок на GitHub, кілька корисних коментарів, близько 200 лайків на Reddit. Лінк на допис тут.

Я ще пробував опублікувати розширення на Discord сервері “iOS development” (11k користувачів) і там майже нульовий результат.

Тому Reddit прям приємно здивував кількістю трафіку.
Structured Header

Нещодавно була задача, де треба було визначити операційну систему клієнта. Перша думка була взяти заголовок User-Agent і з нього виковиряти OS. Але дивлюся є якийсь новий заголовок Sec-CH-UA-Platform, який прямо повертає OS як мені треба. Цей заголовок доволі новий, не всі браузери його відсилають, але якраз те що треба:

Sec-CH-UA-Platform: "macOS"


Без жодного сумніву, я беру в коді цей заголовок і порівнюю його зі значенням, яке я шукаю:

if hdrs["Sec-CH-UA-Platform"] == "macOS":
price = price * rich_k # 💰


Але воно так не працює. Бачите проблему?

Поколупався в інтернеті і знайшов, що цей заголовок сформований по стандарту RFC8941 Structured Field Values for HTTP. Основна ідея, що значення в заголовку є структурованими і можуть бути списками, словниками, рядками, числами і тому подібне. Раніше хто як хотів так і передавав значення у заголовку. Для прикладу, заголовок з Cookie має свій стандарт як передати структуровано всі репʼяшки і його часто вільно інтерпретують парсери.

Якщо повернутися до моєї проблеми, то значення в цьому заголовку передаються браузером якраз по цьому стандарту. Специфікація виглядає так:

Sec-CH-UA-Platform = sf-string

// рядок має бути загорнутий в лапки
sf-string = DQUOTE *chr DQUOTE


Приклад структурованого заголовка по цьому стандарту, який місить тільки рядок на верхньому рівні:

Example-String: "hello world"


В тому прикладі, де я беру заголовок, веб-фреймворк взагалі нічого не знає про те чи буде значення в заголовку структурованим чи ні, тому й повертає все, що йде після двокрапки як воно й записано з лапками чи без них. Тому правильним рішенням було б розпарсити значення структурованого заголовку і вже тоді порівнювати з потрібним мені рядком. Або піти короткою стежкою і обрізати лапки 😄:

hdrs["Sec-CH-UA-Platform"].strip('"')
Стаття в якій автор розказує як зібрати iOS застосунок без Xcode Build System. Вручну запускає компілятор для .swift файлів, лінкує, обробляє .plist файли, копіює runtime бібліотеки, збирає це все в архів, підписує і в кінці запускає це на своєму телефоні.

Мені ця стаття сподобалася, бо ще раз мені нагадує, що під капотом у цих компʼютерів ніякої магії і що не так вже й страшно робити такі речі самому.
Kviklet

З цікавості шукав якийсь self-hosted клієнт для PostgreSQL з SSO, audit log і іншими enterprise штуками для безпечного доступу до бази даних на продкшені. Поки лазив по інтернету найшов цікавий open-source проєкт Kviklet, який вирішує цю проблему через погодження SQL запитів перед їхнім запуском, щось на кшталт pull requests на GitHub.

Розробник пише SQL запит на отримання чи оновлення даних, створює в веб інтерфейсі запит на SQL запит 🙃, хтось з адміністраторів дає добро на цей SQL запит (для прикладу техлід) і далі розробник самостійно запускає SQL запит через веб інтерфейс. Всі дії з базою виконуються через вбудований проксі, тому про кожну таку дію залишається слід в історії для аудиту.

Проєкт на разі безкоштовний і open source, тому цікаво буде поглянути як він буде розвиватися. Як у ваших командах організований доступ до бази даних на продакшені?

🖥 kviklet/kviklet
Please open Telegram to view this post
VIEW IN TELEGRAM