diff options
Diffstat (limited to 'users/tazjin')
99 files changed, 6376 insertions, 2110 deletions
diff --git a/users/tazjin/aoc2022/day1.rs b/users/tazjin/aoc2022/day1.rs new file mode 100644 index 0000000000..078eb25f03 --- /dev/null +++ b/users/tazjin/aoc2022/day1.rs @@ -0,0 +1,27 @@ +// AoC 2022 - day 1. + +fn sum_elf(elf: &str) -> usize { + elf.lines() + .map(|s| s.parse::<usize>().expect("invalid input")) + .sum() +} + +fn group_by_elf(input: &str) -> Vec<usize> { + input.rsplit("\n\n").map(sum_elf).collect() +} + +fn top_elf(input: &str) -> usize { + group_by_elf(&input).into_iter().max().unwrap() +} + +fn top_n_elves(n: usize, input: &str) -> usize { + let mut by_elf = group_by_elf(input); + by_elf.sort_by(|a, b| b.cmp(a)); // high->low + (by_elf[..n]).iter().sum() +} + +fn main() { + let input = std::fs::read_to_string("input").expect("input should be in file named 'input'"); + println!("top elf: {}", top_elf(&input)); + println!("top 3 elves: {}", top_n_elves(3, &input)); +} diff --git a/users/tazjin/aoc2023/day1.el b/users/tazjin/aoc2023/day1.el new file mode 100644 index 0000000000..b1a7faff02 --- /dev/null +++ b/users/tazjin/aoc2023/day1.el @@ -0,0 +1,52 @@ +(require 's) +(require 'f) + +;; task 1 + +(defun digit-p (c) + (and (> c ?0) + (<= c ?9))) + +(defun aocd1-sum-values (lines) + (-sum + (-map (lambda (line) + (let ((digits (-filter #'digit-p (string-to-list line)))) + (string-to-number (string (-first-item digits) (-last-item digits))))) + lines))) + +(let ((lines (s-lines (s-trim (f-read "~/Downloads/input.txt"))))) + (aocd1-sum-values lines)) + +;; task 2 + +(defun replace-written-numbers (input) + (with-temp-buffer + (insert input) + (let ((start 1)) + (while (< start (point-max)) + (format-replace-strings + '(("oneight" . "18") + ("twone" . "21") + ("threeight" . "38") + ("fiveight" . "58") + ("sevenine" . "79") + ("eightwo" . "82") + ("eighthree" . "83") + ("nineight" . "98")) + nil start (min (+ 10 start) (point-max))) + (format-replace-strings + '(("one" . "1") + ("two" . "2") + ("three" . "3") + ("four" . "4") + ("five" . "5") + ("six" . "6") + ("seven" . "7") + ("eight" . "8") + ("nine" . "9")) + nil start (min (+ 5 start) (point-max))) + (setq start (1+ start)))) + (buffer-string))) + +(let ((lines (s-lines (s-trim (f-read "~/Downloads/input.txt"))))) + (aocd1-sum-values (-map #'replace-written-numbers lines))) diff --git a/users/tazjin/aoc2023/day2.el b/users/tazjin/aoc2023/day2.el new file mode 100644 index 0000000000..9374d7862c --- /dev/null +++ b/users/tazjin/aoc2023/day2.el @@ -0,0 +1,64 @@ +(require 'dash) +(require 's) +(require 'f) + +(defvar aoc23-day2-example + + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue +Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red +Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red +Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green") + +;; part 1 + +(cl-defstruct aoc23d2-set red green blue) + +(defun aoc23d2-parse-set (input) + (let ((set (make-aoc23d2-set :red 0 :green 0 :blue 0)) + (colours (-map #'s-trim (s-split "," input)))) + (cl-loop for colour in colours + do (pcase (s-split " " colour t) + (`(,num "red") (setf (aoc23d2-set-red set) (string-to-number num))) + (`(,num "green") (setf (aoc23d2-set-green set) (string-to-number num))) + (`(,num "blue") (setf (aoc23d2-set-blue set) (string-to-number num))))) + set)) + +(cl-defstruct aoc23d2-game id sets) + +(defun aoc23d2-parse-game (input) + (pcase-let* ((`(,id-str ,sets-str) (s-split-up-to ":" input 1 t)) + (game-id (string-to-number (s-chop-left (length "Game ") id-str))) + (sets (-map #'aoc23d2-parse-set (s-split ";" sets-str t)))) + (make-aoc23d2-game :id game-id :sets sets))) + +(defun aoc23d2-game-possible-p (game r g b) + (cl-every (lambda (set) + (and (<= (aoc23d2-set-red set) r) + (<= (aoc23d2-set-green set) g) + (<= (aoc23d2-set-blue set) b))) + (aoc23d2-game-sets game))) + +(let ((input (f-read "~/Downloads/input.txt"))) + (-sum + (-map #'aoc23d2-game-id + (-filter (lambda (g) (aoc23d2-game-possible-p g 12 13 14)) + (-map #'aoc23d2-parse-game (s-lines (s-trim input))))))) + +;; part 2 + +(defun aoc23d2-game-min-cubes-power (game) + (let ((r 0) + (g 0) + (b 0)) + (-each (aoc23d2-game-sets game) + (lambda (set) + (setq r (max r (aoc23d2-set-red set))) + (setq g (max g (aoc23d2-set-green set))) + (setq b (max b (aoc23d2-set-blue set))))) + (* (max 1 r) (max 1 g) (max 1 b)))) + +(let ((input (f-read "~/Downloads/input.txt"))) + (-sum + (-map #'aoc23d2-game-min-cubes-power + (-map #'aoc23d2-parse-game (s-lines (s-trim input)))))) diff --git a/users/tazjin/aoc2023/day3.el b/users/tazjin/aoc2023/day3.el new file mode 100644 index 0000000000..dd39c1b836 --- /dev/null +++ b/users/tazjin/aoc2023/day3.el @@ -0,0 +1,110 @@ +(defun aoc23d3-symbol-p (c) + (not (or (= c ? ) + (and (>= c ?0) + (<= c ?9))))) + +(defun rectangle-for-bounds (bounds) + (let* ((start (save-excursion + (goto-char (car bounds)) + (let ((col (current-column))) + (forward-line -1) + (move-to-column (max 0 (1- col)))) + (point))) + (end (save-excursion + (goto-char (cdr bounds)) + (let ((col (current-column))) + (forward-line 1) + (move-to-column (1+ col))) + (point)))) + (list start end))) + +(defun get-machine-part () + (interactive) + (when-let* ((num-raw (number-at-point)) + (num (abs num-raw)) + ;; handles negative number edge case (bounds contain the `-') + (bounds-raw (bounds-of-thing-at-point 'number)) + (bounds (if (< num-raw 0) + (cons (1- (car bounds-raw)) (cdr bounds-raw)) + bounds-raw)) + (rectangle (rectangle-for-bounds bounds)) + (neighbours (apply #'concat + (apply #'extract-rectangle rectangle)))) + (if (-any #'aoc23d3-symbol-p (string-to-list neighbours)) + (cons num rectangle) + (cons nil rectangle)))) + + +(defun find-machine-parts (input) + (with-temp-buffer + (insert input) + (goto-char (point-min)) + (save-excursion + (replace-string "." " ")) + + (cl-loop while (forward-word) + for result = (get-machine-part) + when (car result) collect (car result)))) + + +;; debugging + +(defvar aoc23d3-example "467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598..") + +(defvar aoc23d3-example2 "12.......*.. ++.........34 +.......-12.. +..78........ +..*....60... +78.......... +.......23... +....90*12... +............ +2.2......12. +.*.........* +1.1.......56") + +(defvar aoc23d3-example3 "243. +..*. +....") + +(defun aoc23d3-debug (p) + "Interactive debugger for the solution, can be bound to a key in +an input buffer. Dots should already have been replaced with +spaces." + (interactive "P") + (unless p + (goto-char aoc23d3-last)) + (rectangle-mark-mode 1) + (forward-word) + (setq aoc23d3-last (point)) + (pcase (get-machine-part) + (`(nil ,b ,e) (progn (set-mark b) + (goto-char e) + (set-face-attribute 'region nil :background "#FAA0A0"))) + (`(,num ,b ,e) (progn (set-mark b) + (goto-char e) + (set-face-attribute 'region nil :background "#d1ffbd"))) + (other (deactivate-mark)))) + +(cl-assert (= 4361 (-sum (find-machine-parts aoc23d3-example))) nil + "example from website is working") + +(cl-assert (= 413 (-sum (find-machine-parts aoc23d3-example2))) nil + "example from subreddit is working") + +(cl-assert (= 243 (-sum (find-machine-parts aoc23d3-example3))) nil + "example from telegram is working") + +;; day 1 (incomplete) + +(-sum (find-machine-parts (s-trim (f-read "~/Downloads/input.txt")))) diff --git a/users/tazjin/blog/default.nix b/users/tazjin/blog/default.nix index 85e9d29b3a..60c79f0941 100644 --- a/users/tazjin/blog/default.nix +++ b/users/tazjin/blog/default.nix @@ -8,6 +8,7 @@ let config = { name = "tazjin's blog"; baseUrl = "https://tazj.in/blog"; + staticUrl = "https://tazj.in/static/"; footer = '' <p class="footer"> diff --git a/users/tazjin/blog/posts.nix b/users/tazjin/blog/posts.nix index f7f50d6f1a..a95a50d766 100644 --- a/users/tazjin/blog/posts.nix +++ b/users/tazjin/blog/posts.nix @@ -1,6 +1,19 @@ # This file defines all the blog posts. [ { + key = "reliably-switch-buffers"; + title = "Зачем reliably-switch-buffers?"; + content = ./posts/reliably-switch-buffers.md; + date = 1692882000; + } + { + key = "tvix-eval-talk-2023"; + title = "[доклад] tvix-eval, имплементация языка Nix на Rust"; + date = 1694102400; + content = ./posts/tvix-eval-talk-2023.md; + tagfilter = false; + } + { key = "emacs-is-underrated"; title = "Emacs is the most underrated tool"; date = 1581286656; @@ -46,6 +59,7 @@ date = 1423995834; content = ./posts/sick-in-sweden.md; oldKey = "1423995834"; + listed = false; } { key = "nsa-zettabytes"; diff --git a/users/tazjin/blog/posts/nixery-layers.md b/users/tazjin/blog/posts/nixery-layers.md index 38ca2294a8..26526d11b5 100644 --- a/users/tazjin/blog/posts/nixery-layers.md +++ b/users/tazjin/blog/posts/nixery-layers.md @@ -267,6 +267,6 @@ NixCon talk][talk] about Nixery for a review of some of this, and some demos. [nixery.dev]: https://nixery.dev [dominator trees]: https://en.wikipedia.org/wiki/Dominator_(graph_theory) [gonum/graph]: https://godoc.org/gonum.org/v1/gonum/graph -[layers.go]: https://cs.tvl.fyi/depot/-/blob/tools/nixery/builder/layers.go +[layers.go]: https://cs.tvl.fyi/depot/-/blob/tools/nixery/layers/layers.go [popcount]: https://cs.tvl.fyi/depot/-/tree/tools/nixery/popcount [talk]: https://www.youtube.com/watch?v=pOI9H4oeXqA diff --git a/users/tazjin/blog/posts/reliably-switch-buffers.md b/users/tazjin/blog/posts/reliably-switch-buffers.md new file mode 100644 index 0000000000..ec56c4b2d0 --- /dev/null +++ b/users/tazjin/blog/posts/reliably-switch-buffers.md @@ -0,0 +1,18 @@ +Вчера вечером написал некоторые патчи для моего emacs-конфига. Их на самом деле давно уже хотел написать, они решают маленькие проблемы которые мне постоянно мешали. Об одной из проблем я хочу рассказать, потому что она привела к тому, что "порог раздражения" был переступлен. + +Emacs у меня основная часть своей рабочей среды. Он у меня является, конечно, текстовым редактором, но и еще менеджером окон, мэйл-клиентом, чат-клиентом и много другого. + +Внутри emacs есть концепция "буферов", один буфер может быть один открытый файл в текстовом редакторе, один чат на Телеграме, или одно десктопное окно (например, браузер). Навигация между ними осуществляется с помощью команды `switch-to-buffer` (или кое-каких альтернатив, например `ivy-switch-buffer`, `helm-switch-buffer` и так далее). Буфер - на стороне emacs-lisp является объектом с некоторыми полями. Одно из них: `buffer-name`. + +У всех buffer-switch команд есть одинаковая проблема: Они берут список буферов из emacs, показывают *имена* буферов пользователю, и в результате получают выбранное *имя*. Затем они просят emacs открыть буфер с этим именем. + +Кто-то наверно уже понял какая тут проблема. Имени буферов могут меняться, и да, не только могут, но и делают! Например, Телеграм-клиент может показать каличество непрочитанных сообщений в названии, окно с Яндекс Музыкой меняет названия по треку, и так далее. Получается довольно часто такая ситуация, что название меняется при выборе буфера, и `switch-to-buffer` больше не найдет выбранный буфер и просто открывает новый, пустой буфер с старым названием! Когда разработывали эти команды в emacs (да, это совершенно давно, где-то в 70х/80х, большинства нас пока не было тогда!), они никогда не сталкивались с такими ситуациями, и это решение, которое тогда хорошо работало теперь больше просто не адекватно. + +Фикс был не очень сложным. Вместо списка имен буферов создаю alist с названием и *с самим объектом*, и после выбора буфера с списка передаю именно этот объект, а не только его название, в функтцию, которая открывает буфер. + +Коммит с этой новой функцией здесь: cl/9147 +Советую её особенно всем пользователям EXWM! + +Для меня это настоящее улучшение жизни. Конечно, это странно звучит, но даже если бы у меня была такая проблема всего раз в день, это каким-то образом привело бы к ухудшению моего настроения. Как маленький камешек в твоем ботинке. + +Выньте камни из своих ботинок! diff --git a/users/tazjin/blog/posts/reversing-watchguard-vpn.md b/users/tazjin/blog/posts/reversing-watchguard-vpn.md index 8968dc8645..e000d7a764 100644 --- a/users/tazjin/blog/posts/reversing-watchguard-vpn.md +++ b/users/tazjin/blog/posts/reversing-watchguard-vpn.md @@ -1,5 +1,5 @@ TIP: WatchGuard has -[responded](https://www.reddit.com/r/netsec/comments/5tg0f9/reverseengineering_watchguard_mobile_vpn/dds6knx/) +[responded](https://web.archive.org/web/20230326041952/https://www.reddit.com/r/netsec/comments/5tg0f9/reverseengineering_watchguard_mobile_vpn/dds6knx/) to this post on Reddit. If you haven\'t read the post yet I\'d recommend doing that first before reading the response to have the proper context. diff --git a/users/tazjin/blog/posts/tvix-eval-talk-2023.md b/users/tazjin/blog/posts/tvix-eval-talk-2023.md new file mode 100644 index 0000000000..4a0ec56881 --- /dev/null +++ b/users/tazjin/blog/posts/tvix-eval-talk-2023.md @@ -0,0 +1,19 @@ +7 сентября я выступил с докладом про реализацию языка Nix на Rust, на +[Московском Rust-митапе][rustmsk] / [Московском клубе +программистов][progmsk]. + +<iframe width="800" height="500" src="https://www.youtube.com/embed/7zS2_ZhwPfY?start=4013" title="RUST - современный язык программирования" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> + +Вот все связанные с ним ссылки, которые могут быть интересны: + +* [Tvix](https://tvix.dev), главный сайт проекта +* [TVL](https://tvl.fyi), наше онлайн-сообщество +* [Tvixbolt](https://bolt.tvix.dev/), наш "godbolt" для tvix +* [MMTk](https://www.mmtk.io/), Rust-библиотека с компонентами для garbage-collection +* [Интервью / доклад](https://www.youtube.com/live/0Lhahzs-Wos?si=BlFDVBUPsIpHg0p5), Nix -- не только пакетный менеджер +* [NixCon 2023](https://2023.nixcon.org/) +* [Yew](https://yew.rs/), WASM-фреймворк для Rust +* [tazlog](https://t.me/tazlog), мой канал на Телеге + +[rustmsk]: https://t.me/ruRust_msk +[progmsk]: https://prog.msk.ru/ diff --git a/users/tazjin/chase-geese/default.nix b/users/tazjin/chase-geese/default.nix new file mode 100644 index 0000000000..3549f75868 --- /dev/null +++ b/users/tazjin/chase-geese/default.nix @@ -0,0 +1,13 @@ +# Helpers for mounting GeeseFS into the right place. +{ depot, pkgs, ... }: + +pkgs.writeShellScriptBin "chase-geese" '' + set -ueo pipefail + + echo "Fetching credentials ..." + eval $(pass show keys/tazjin-geesefs) + + echo "Mounting the cloud ..." + mkdir -p ~/cloud + ${depot.third_party.geesefs}/bin/geesefs tazjins-files ~/cloud +'' diff --git a/users/tazjin/elisp-deps/deps.el b/users/tazjin/elisp-deps/deps.el new file mode 100644 index 0000000000..954d71cfba --- /dev/null +++ b/users/tazjin/elisp-deps/deps.el @@ -0,0 +1,83 @@ +;; Visualise the internal structure of an Emacs Lisp file using +;; Graphviz. +;; +;; Entry point is the function `edeps-analyse-file'. + +(require 'map) + +(defun edeps-read-defs (file-name) + "Stupidly read all definitions from an Emacs Lisp file. This only +considers top-level forms, where the first element of the form is +a symbol whose name contains the string `def', and where the +second element is a symbol. + +Returns a hashmap of all these symbols with the remaining forms +in their bodies." + + (with-temp-buffer + (insert-file-contents file-name) + (goto-char (point-min)) + + (let ((symbols (make-hash-table))) + (condition-case _err + (while t + (let ((form (read (current-buffer)))) + (when (and (listp form) + (symbolp (car form)) + (string-match "def" (symbol-name (car form))) + (symbolp (cadr form))) + (when (and (map-contains-key symbols (cadr form)) + ;; generic methods have multiple definitions + (not (eq (car form) 'cl-defmethod))) + (error "Duplicate symbol: %s" (symbol-name (cadr form)))) + + (map-put! symbols (cadr form) + (cons (car form) (cddr form)))))) + (end-of-file symbols))))) + +(defun edeps-analyse-structure (symbols) + "Analyse the internal structure of the symbols found by +edeps-read-defs, and return a hashmap with the results of the +analysis. The hashmap uses the symbols as keys, " + (let ((deps (make-hash-table))) + (map-do + (lambda (sym val) + (dolist (expr (flatten-list (cdr val))) + (when (map-contains-key symbols expr) + (map-put! deps expr (cons sym (ht-get deps expr)))))) + symbols) + deps)) + +(defun edeps-graph-deps (symbols deps) + (with-temp-buffer + (insert "digraph edeps {\n") + + ;; List all symbols first + (insert " subgraph {\n") + (map-do + (lambda (sym val) + (insert " " (format "\"%s\" [label=\"%s\\n(%s)\"];\n" sym sym (car val)))) + symbols) + (insert " }\n\n") + + ;; Then drop all the edges in there .. + (insert " subgraph {\n") + (map-do + (lambda (sym deps) + (dolist (dep deps) + (insert " " (format "\"%s\" -> \"%s\";\n" dep sym)))) + deps) + (insert " }\n") + + (insert "}\n") + (buffer-string))) + +(defun edeps-analyse-file (infile outfile) + "Produces a dot-graph in OUTFILE from an internal structural +analysis of INFILE. This can be graphed using the graphviz +package." + (let* ((symbols (edeps-read-defs infile)) + (deps (edeps-analyse-structure symbols))) + (with-temp-buffer + (insert (edeps-graph-deps symbols deps)) + (write-file outfile)))) diff --git a/users/tazjin/emacs/config/bindings.el b/users/tazjin/emacs/config/bindings.el index 1feb9faf81..d8b63e33e4 100644 --- a/users/tazjin/emacs/config/bindings.el +++ b/users/tazjin/emacs/config/bindings.el @@ -1,11 +1,11 @@ +;; Switch buffers reliably in the face of spurious renames. +(global-set-key (kbd "C-x b") #'reliably-switch-buffer) + ;; Font size (define-key global-map (kbd "C-=") 'increase-default-text-scale) ;; '=' because there lies '+' (define-key global-map (kbd "C--") 'decrease-default-text-scale) (define-key global-map (kbd "C-x C-0") 'set-default-text-scale) -;; What does <tab> do? Well, it depends ... -(define-key prog-mode-map (kbd "<tab>") #'company-indent-or-complete-common) - ;; imenu instead of insert-file (global-set-key (kbd "C-x i") 'imenu) @@ -15,7 +15,6 @@ ;; Start eshell or switch to it if it's active. (global-set-key (kbd "C-x m") 'eshell) -(global-set-key (kbd "C-x C-p") 'browse-repositories) (global-set-key (kbd "M-g M-g") 'goto-line-with-feedback) ;; Miscellaneous editing commands @@ -23,7 +22,7 @@ (global-set-key (kbd "C-c a") 'align-regexp) (global-set-key (kbd "C-c m") 'mc/mark-dwim) -;; Browse URLs (very useful for Gitlab's SSH output!) +;; Browse URLs (very useful for Gerrit's push output, etc!) (global-set-key (kbd "C-c b p") 'browse-url-at-point) (global-set-key (kbd "C-c b b") 'browse-url) @@ -34,23 +33,17 @@ ;; Open a file in project: (global-set-key (kbd "C-c f") 'project-find-file) -;; Search in a project -(global-set-key (kbd "C-c r g") 'rg-in-project) - ;; Open a file via magit: (global-set-key (kbd "C-c C-f") #'magit-find-file-worktree) ;; Insert TODO comments (global-set-key (kbd "C-c t") 'insert-todo-comment) -;; Make sharing music easier -(global-set-key (kbd "s-s w") #'songwhip-lookup-url) - ;; Open the depot (global-set-key (kbd "s-s d") #'tvl-depot-status) -;; Open any repo through zoxide -(global-set-key (kbd "s-s r") #'zoxide-open-magit) +;; Open any project through zoxide +(global-set-key (kbd "s-s r") #'zoxide-open-project) ;; Add subthread collapsing to notmuch-show. ;; diff --git a/users/tazjin/emacs/config/custom.el b/users/tazjin/emacs/config/custom.el index 91eaf69ae5..3e9a9dcd06 100644 --- a/users/tazjin/emacs/config/custom.el +++ b/users/tazjin/emacs/config/custom.el @@ -7,8 +7,6 @@ '(ac-delay 0.2) '(avy-background t) '(cargo-process--enable-rust-backtrace 1) - '(company-auto-complete (quote (quote company-explicit-action-p))) - '(company-idle-delay 0.5) '(custom-safe-themes (quote ("d61fc0e6409f0c2a22e97162d7d151dee9e192a90fa623f8d6a071dbf49229c6" "3c83b3676d796422704082049fc38b6966bcad960f896669dfc21a7a37a748fa" "89336ca71dae5068c165d932418a368a394848c3b8881b2f96807405d8c6b5b6" default))) diff --git a/users/tazjin/emacs/config/desktop.el b/users/tazjin/emacs/config/desktop.el index 0ee53276a1..aa232fec2f 100644 --- a/users/tazjin/emacs/config/desktop.el +++ b/users/tazjin/emacs/config/desktop.el @@ -4,14 +4,15 @@ ;; window-management (EXWM) as well as additional system-wide ;; commands. -(require 'dash) (require 'exwm) (require 'exwm-config) (require 'exwm-randr) (require 'exwm-systemtray) (require 'exwm-xim ) (require 'f) +(require 'ring) (require 's) +(require 'seq) (defcustom tazjin--screen-lock-command "tazjin-screen-lock" "Command to execute for locking the screen." @@ -69,36 +70,17 @@ human-accessible titles." (pcase (list (or exwm-class-name "unknown") (or exwm-title "unknown")) - ;; In Cider windows, rename the class and keep the workspace/file - ;; as the title. - (`("Google-chrome" ,(and (pred (lambda (title) (s-ends-with? " - Cider" title))) title)) - (format "Cider<%s>" (s-chop-suffix " - Cider" title))) - (`("Google-chrome" ,(and (pred (lambda (title) (s-ends-with? " - Cider V" title))) title)) - (format "Cider V<%s>" (s-chop-suffix " - Cider V" title))) - - ;; Attempt to detect IRCCloud windows via their title, which is a - ;; combination of the channel name and network. - ;; - ;; This is what would often be referred to as a "hack". The regexp - ;; will not work if a network connection buffer is selected in - ;; IRCCloud, but since the title contains no other indication that - ;; we're dealing with an IRCCloud window - (`("Google-chrome" - ,(and (pred (lambda (title) - (s-matches? "^[\*\+]\s#[a-zA-Z0-9/\-]+\s\|\s[a-zA-Z\.]+$" title))) - title)) - (format "IRCCloud<%s>" title)) - - ;; For other Chrome windows, make the title shorter. - (`("Google-chrome" ,title) - (format "Chrome<%s>" (s-truncate 42 (s-chop-suffix " - Google Chrome" title)))) - - ;; Gnome-terminal -> Term - (`("Gnome-terminal" ,title) - ;; fish-shell buffers contain some unnecessary whitespace and - ;; such before the current working directory. This can be - ;; stripped since most of my terminals are fish shells anyways. - (format "Term<%s>" (s-trim-left (s-chop-prefix "fish" title)))) + ;; Yandex.Music -> `Я.Music<... stuff ...>' + (`("Chromium-browser" ,(and (pred (lambda (title) (s-starts-with? "Yandex.Music - " title))) title)) + (format "Я.Music<%s>" (s-chop-prefix "Yandex.Music - " title))) + + ;; For other Chromium windows, make the title shorter. + (`("Chromium-browser" ,title) + (format "Chromium<%s>" (s-truncate 42 (s-chop-suffix " - Chromium" title)))) + + ;; similarly for Firefox + (`("firefox" ,title) + (format "FF<%s>" title)) ;; Quassel buffers ;; @@ -120,9 +102,6 @@ (`(,class ,title) (format "%s<%s>" class (s-truncate 12 title))))) ;; EXWM launch configuration -;; -;; This used to use use-package, but when something breaks use-package -;; it doesn't exactly make debugging any easier. (let ((titlef (lambda () (exwm-workspace-rename-buffer (create-window-name))))) @@ -130,117 +109,57 @@ (add-hook 'exwm-update-title-hook titlef)) (fringe-mode 3) -(exwm-enable) - -;; Create 10 EXWM workspaces -(setq exwm-workspace-number 10) - -;; 's-N': Switch to certain workspace, but switch back to the previous -;; one when tapping twice (emulates i3's `back_and_forth' feature) -(defvar *exwm-workspace-from-to* '(-1 . -1)) -(defun exwm-workspace-switch-back-and-forth (target-idx) - ;; If the current workspace is the one we last jumped to, and we are - ;; asked to jump to it again, set the target back to the previous - ;; one. - (when (and (eq exwm-workspace-current-index (cdr *exwm-workspace-from-to*)) - (eq target-idx exwm-workspace-current-index)) - (setq target-idx (car *exwm-workspace-from-to*))) - - (setq *exwm-workspace-from-to* - (cons exwm-workspace-current-index target-idx)) - - (exwm-workspace-switch-create target-idx)) -(dotimes (i 10) - (exwm-input-set-key (kbd (format "s-%d" i)) - `(lambda () - (interactive) - (exwm-workspace-switch-back-and-forth ,i)))) - -;; Implement MRU functionality for EXWM workspaces, making it possible -;; to jump to the previous/next workspace very easily. -(defvar *recent-workspaces* nil - "List of the most recently used EXWM workspaces.") - -(defvar *workspace-jumping-to* nil - "What offset in the workspace history are we jumping to?") - -(defvar *workspace-history-position* 0 - "Where in the workspace history are we right now?") - -(defun update-recent-workspaces () - "Hook to run on every workspace switch which will prepend the new -workspace to the MRU list, unless we are already on that -workspace. Does not affect the MRU list if a jump is -in-progress." +;; tab-bar related config +(setq tab-bar-show 1) +(setq tab-bar-tab-hints t) - (if *workspace-jumping-to* - (setq *workspace-history-position* *workspace-jumping-to* - *workspace-jumping-to* nil) +(setq tab-bar-format + '(tab-bar-format-history + tab-bar-format-tabs tab-bar-separator + tab-bar-format-align-right tab-bar-format-global)) - ;; reset the history position to the front on a normal jump - (setq *workspace-history-position* 0) - - (unless (eq exwm-workspace-current-index (car *recent-workspaces*)) - (setq *recent-workspaces* (cons exwm-workspace-current-index - (-take 9 *recent-workspaces*)))))) - -(add-to-list 'exwm-workspace-switch-hook #'update-recent-workspaces) - -(defun switch-to-previous-workspace () - "Switch to the previous workspace in the MRU workspace list." - (interactive) +(setq tab-bar-new-tab-choice + (lambda () (get-buffer-create "*scratch*"))) - (let* (;; the previous workspace is one position further down in the - ;; workspace history - (position (+ *workspace-history-position* 1)) - (target-idx (elt *recent-workspaces* position))) - (if (not target-idx) - (message "No previous workspace in history!") +(tab-bar-mode 1) - (setq *workspace-jumping-to* position) - (exwm-workspace-switch target-idx)))) +(setq x-no-window-manager t) ;; TODO(tazjin): figure out when to remove this +(exwm-enable) +(exwm-randr-enable) -(exwm-input-set-key (kbd "s-b") #'switch-to-previous-workspace) +;; Tab-management shortcuts -(defun switch-to-next-workspace () - "Switch to the next workspace in the MRU workspace list." +(defun tab-bar-select-or-return () + "This function behaves like `tab-bar-select-tab', except it calls +`tab-recent' if asked to jump to the current tab. This simulates +the back&forth behaviour of i3." (interactive) - - (if (= *workspace-history-position* 0) - (message "No next workspace in history!") - (let* (;; The next workspace is one position further up in the - ;; history. This always exists unless someone messed with - ;; it. - (position (- *workspace-history-position* 1)) - (target-idx (elt *recent-workspaces* position))) - (setq *workspace-jumping-to* position) - (exwm-workspace-switch target-idx)))) - -(exwm-input-set-key (kbd "s-f") #'switch-to-next-workspace) - -;; Provide a binding for jumping to a buffer on a workspace. -(defun exwm-jump-to-buffer () - "Jump to a workspace on which the target buffer is displayed." - (interactive) - (let ((exwm-layout-show-all-buffers nil) - (initial exwm-workspace-current-index)) - (call-interactively #'exwm-workspace-switch-to-buffer) - ;; After jumping, update the back-and-forth list like on a direct - ;; index jump. - (when (not (eq initial exwm-workspace-current-index)) - (setq *exwm-workspace-from-to* - (cons initial exwm-workspace-current-index))))) - -(exwm-input-set-key (kbd "C-c j") #'exwm-jump-to-buffer) + (let* ((key (event-basic-type last-command-event)) + (tab (if (and (characterp key) (>= key ?1) (<= key ?9)) + (- key ?0) + 0)) + (current (1+ (tab-bar--current-tab-index)))) + (if (eq tab current) + (tab-recent) + (tab-bar-select-tab tab)))) + +(dotimes (i 8) + (exwm-input-set-key (kbd (format "s-%d" (+ 1 i))) #'tab-bar-select-or-return)) + +(exwm-input-set-key (kbd "s-9") #'tab-last) +(exwm-input-set-key (kbd "s-f") #'tab-next) +(exwm-input-set-key (kbd "s-b") #'tab-recent) +(exwm-input-set-key (kbd "s-w") #'tab-close) +(exwm-input-set-key (kbd "s-n") #'tab-new) ;; Launch applications / any command with completion (dmenu style!) -(exwm-input-set-key (kbd "s-d") #'counsel-linux-app) +(exwm-input-set-key (kbd "s-d") #'run-xdg-app) (exwm-input-set-key (kbd "s-x") #'run-external-command) (exwm-input-set-key (kbd "s-p") #'password-store-lookup) -;; Add X11 terminal selector to a key -(exwm-input-set-key (kbd "C-x t") #'ts/switch-to-terminal) +;; Add vterm selector to a key +(exwm-input-set-key (kbd "s-v") #'ts/switch-to-terminal) ;; Toggle between line-mode / char-mode (exwm-input-set-key (kbd "C-c C-t C-t") #'exwm-input-toggle-keyboard) @@ -267,10 +186,6 @@ in-progress." (bind-xkb "no" "k n") (bind-xkb "ru" "k r") (bind-xkb "se" "k s") - -;; These are commented out because Emacs no longer starts (??) if -;; they're set at launch. -;; (bind-xkb "us" "л г") (bind-xkb "de" "л в") (bind-xkb "no" "л т") @@ -282,9 +197,8 @@ in-progress." (push ?\C-\\ exwm-input-prefix-keys) ;; Line-editing shortcuts -(exwm-input-set-simulation-keys - '(([?\C-d] . delete) - ([?\C-w] . ?\C-c))) +(exwm-input-set-simulation-key (kbd "C-d") (kbd "DEL")) +(exwm-input-set-simulation-key (kbd "C-w") (kbd "C-c")) ;; Show time & battery status in the mode line (display-time-mode) @@ -293,76 +207,123 @@ in-progress." ;; enable display of X11 system tray within Emacs (exwm-systemtray-enable) -;; Configure xrandr (multi-monitor setup). - -(defun set-randr-config (screens) - (setq exwm-randr-workspace-monitor-plist - (-flatten (-map (lambda (screen) - (-map (lambda (screen-id) (list screen-id (car screen))) (cdr screen))) - screens)))) +;; Multi-monitor configuration. +;; +;; With tab-bar-mode, each monitor only displays at most one +;; workspace. Workspaces are only created, never deleted, meaning that +;; the number of workspaces will be equivalent to the maximum number +;; of displays that were connected during a session. +;; +;; The first workspace is special: It is kept on the primary monitor. -;; Layouts for Tverskoy (X13 AMD laptop) -(defun randr-tverskoy-layout-single () - "Laptop screen only!" +(defun exwm-assign-workspaces () + "Assigns workspaces to the currently existing monitors, putting +the first one on the primary display and allocating the others +dynamically if needed in no particular order." (interactive) - (set-randr-config '(("eDP" (number-sequence 0 9)))) - (shell-command "xrandr --output eDP --auto --primary") - (shell-command "xrandr --output HDMI-A-0 --off") - (exwm-randr-refresh)) - -(defun randr-tverskoy-split-workspace () - "Split the workspace across two screens, assuming external to the left." + (let* ((randr-monitors (exwm-randr--get-monitors)) + (primary (car randr-monitors)) + (all-monitors (seq-map #'car (cadr randr-monitors))) + (sorted-primary-first (seq-sort (lambda (a b) + (or (equal a primary) + (< a b))) + all-monitors)) + ;; assign workspace numbers to each monitor ... + (workspace-assignments + (flatten-list (seq-map-indexed (lambda (monitor idx) + (list idx monitor)) + sorted-primary-first)))) + ;; ensure that the required workspaces exist + (exwm-workspace-switch-create (- (seq-length all-monitors) 1)) + + ;; update randr config + (setq exwm-randr-workspace-monitor-plist workspace-assignments) + (exwm-randr-refresh) + + ;; leave focus on primary workspace + (exwm-workspace-switch 0))) + +(defun list-available-monitors () + "List connected, but unused monitors." + (let* ((all-connected + (seq-map (lambda (line) (car (s-split " " line))) + (s-lines (s-trim (shell-command-to-string "xrandr | grep connected | grep -v disconnected"))))) + (all-active (seq-map #'car (cadr (exwm-randr--get-monitors))))) + (seq-filter (lambda (s) (not (seq-contains-p all-active s))) + all-connected))) + +(defun exwm-enable-monitor () + "Interactively construct an EXWM invocation that enable the +given monitor and assigns a workspace to it." (interactive) - (set-randr-config - '(("HDMI-A-0" 1 2 3 4 5 6 7 8 9) - ("eDP" 0))) - (shell-command "xrandr --output HDMI-A-0 --left-of eDP --auto") - (exwm-randr-refresh)) - -(defun randr-tverskoy-tv () - "Split off a workspace to the TV over HDMI." + (let* ((monitors (list-available-monitors)) + (primary (car (exwm-randr--get-monitors))) + (monitor (pcase (seq-length monitors) + (0 (error "No available monitors.")) + (1 (car monitors)) + (_ + (completing-read "Which monitor? " (list-available-monitors) nil t)))) + + (configurations `(("secondary (left)" . ,(format "--left-of %s" primary)) + ("secondary (right)" . ,(format "--right-of %s" primary)) + ("primary (left)" . ,(format "--left-of %s --primary" primary)) + ("primary (right)" . ,(format "--right-of %s --primary" primary)) + ("mirror" . ,(format "--same-as %s" primary)))) + + (where (completing-read (format "%s should be " monitor) + (seq-map #'car configurations) + nil t)) + (xrandr-pos (cdr (assoc where configurations))) + (xrandr-cmd (format "xrandr --output %s --auto %s" monitor xrandr-pos))) + (message "Invoking '%s'" xrandr-cmd) + (shell-command xrandr-cmd) + (exwm-assign-workspaces))) + +(defun exwm-disable-monitor () + "Interactively choose a monitor to disable." (interactive) - (set-randr-config - '(("eDP" 1 2 3 4 5 6 7 8 9) - ("HDMI-A-0" 0))) - (shell-command "xrandr --output HDMI-A-0 --left-of eDP --mode 1920x1080") - (exwm-randr-refresh)) + (let* ((all (exwm-randr--get-monitors)) + (active (seq-map #'car (cadr all))) + (monitor (if (> (seq-length active) 1) + (completing-read "Disable which monitor? " active nil t) + (error "Only one monitor is active!"))) -;; Layouts for frog (desktop) + ;; If this monitor was primary, pick another active one instead. + (remaining (seq-filter (lambda (s) (not (equal s monitor))) active)) + (new-primary + (when (equal monitor (car all)) + (pcase (seq-length remaining) + (1 (car remaining)) + (_ (completing-read "New primary? " remaining nil t)))))) -(defun randr-frog-layout-right-only () - "Use only the right screen on frog." - (interactive) - (set-randr-config `(("DisplayPort-0" ,(number-sequence 0 9)))) - (shell-command "xrandr --output DisplayPort-0 --off") - (shell-command "xrandr --output DisplayPort-1 --auto --primary")) + (when new-primary + (shell-command (format "xrandr --output %s --primary" new-primary))) -(defun randr-frog-layout-both () - "Use the left and right screen on frog." - (interactive) - (set-randr-config `(("DisplayPort-0" 1 2 3 4 5) - ("DisplayPort-1" 6 7 8 9 0))) + (shell-command (format "xrandr --output %s --off" monitor)) + (exwm-assign-workspaces))) - (shell-command "xrandr --output DisplayPort-0 --auto --primary --left-of DisplayPort-1") - (shell-command "xrandr --output DisplayPort-1 --auto --right-of DisplayPort-0 --rotate left")) +(defun exwm-switch-monitor () + "Switch focus to another monitor by name." + (interactive) -(pcase (s-trim (shell-command-to-string "hostname")) - ("tverskoy" - (exwm-input-set-key (kbd "s-m s") #'randr-tverskoy-layout-single) - (exwm-input-set-key (kbd "s-m 2") #'randr-tverskoy-split-workspace)) + ;; TODO: Filter out currently active? How to determine it? + (let* ((target (completing-read "Switch to monitor: " + (seq-map #'car (cadr (exwm-randr--get-monitors))) + nil t)) + (target-workspace + (cl-loop for (workspace screen) on exwm-randr-workspace-monitor-plist by #'cddr + when (equal screen target) return workspace))) + (exwm-workspace-switch target-workspace))) - ("frog" - (exwm-input-set-key (kbd "s-m b") #'randr-frog-layout-both) - (exwm-input-set-key (kbd "s-m r") #'randr-frog-layout-right-only))) +(exwm-input-set-key (kbd "s-m e") #'exwm-enable-monitor) +(exwm-input-set-key (kbd "s-m d") #'exwm-disable-monitor) +(exwm-input-set-key (kbd "s-m o") #'exwm-switch-monitor) ;; Notmuch shortcuts as EXWM globals ;; (g m => gmail) (exwm-input-set-key (kbd "s-g m") #'notmuch) -(exwm-input-set-key (kbd "s-g M") #'counsel-notmuch) - -(exwm-randr-enable) ;; Let buffers move seamlessly between workspaces by making them ;; accessible in selectors on all frames. diff --git a/users/tazjin/emacs/config/functions.el b/users/tazjin/emacs/config/functions.el index f64907a591..68a384d20f 100644 --- a/users/tazjin/emacs/config/functions.el +++ b/users/tazjin/emacs/config/functions.el @@ -2,9 +2,7 @@ (require 'dash) (require 'map) -(defun load-file-if-exists (filename) - (if (file-exists-p filename) - (load filename))) +(require 'gio-list-apps) ;; native module! (defun goto-line-with-feedback () "Show line numbers temporarily, while prompting for the line number input" @@ -17,24 +15,19 @@ (goto-line target))) (setq-local display-line-numbers nil))) -;; These come from the emacs starter kit - (defun esk-add-watchwords () (font-lock-add-keywords nil '(("\\<\\(FIX\\(ME\\)?\\|TODO\\|DEBUG\\|HACK\\|REFACTOR\\|NOCOMMIT\\)" 1 font-lock-warning-face t)))) +(add-hook 'prog-mode-hook 'esk-add-watchwords) + (defun esk-sudo-edit (&optional arg) (interactive "p") (if (or arg (not buffer-file-name)) (find-file (concat "/sudo:root@localhost:" (read-file-name "File: "))) (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))) -;; Open the NixOS man page -(defun nixos-man () - (interactive) - (man "configuration.nix")) - ;; Get the nix store path for a given derivation. ;; If the derivation has not been built before, this will trigger a build. (defun nix-store-path (derivation) @@ -114,7 +107,9 @@ the GPG agent correctly." nil ;; predicate t ;; require-match )) - (password (auth-source-pass-get 'secret entry))) + (password (or (let ((epa-suppress-error-buffer t)) + (auth-source-pass-get 'secret entry)) + (error "failed to decrypt '%s', wrong password?" entry)))) (password-store-clear) (kill-new password) (setq password-store-kill-ring-pointer kill-ring-yank-pointer) @@ -124,23 +119,6 @@ the GPG agent correctly." (run-at-time (password-store-timeout) nil 'password-store-clear)))) -(defun browse-repositories () - "Select a git repository and open its associated magit buffer." - - (interactive) - (magit-status - (completing-read "Repository: " (magit-list-repos)))) - -(defun bottom-right-window-p () - "Determines whether the last (i.e. bottom-right) window of the - active frame is showing the buffer in which this function is - executed." - (let* ((frame (selected-frame)) - (right-windows (window-at-side-list frame 'right)) - (bottom-windows (window-at-side-list frame 'bottom)) - (last-window (car (seq-intersection right-windows bottom-windows)))) - (eq (current-buffer) (window-buffer last-window)))) - (defhydra mc/mark-more-hydra (:color pink) ("<up>" mc/mmlte--up "Mark previous like this") ("<down>" mc/mmlte--down "Mark next like this") @@ -178,27 +156,6 @@ the GPG agent correctly." mc/mark-more-hydra/mmlte--up mc/mark-more-hydra/nil)) -(defun memespace-region () - "Make a meme out of it." - - (interactive) - (let* ((start (region-beginning)) - (end (region-end)) - (memed - (message - (s-trim-right - (apply #'string - (-flatten - (nreverse - (-reduce-from (lambda (acc x) - (cons (cons x (-repeat (+ 1 (length acc)) 32)) acc)) - '() - (string-to-list (buffer-substring-no-properties start end)))))))))) - - (save-excursion (delete-region start end) - (goto-char start) - (insert memed)))) - (defun insert-todo-comment (prefix todo) "Insert a comment at point with something for me to do." @@ -241,11 +198,16 @@ the GPG agent correctly." (if prefix (text-scale-adjust 0) (set-face-attribute 'default nil :height (or to 120)))) -(defun scrot-select () +(defun screenshot-select (filename) "Take a screenshot based on a mouse-selection and save it to ~/screenshots." - (interactive) - (shell-command "scrot '$a_%Y-%m-%d_%s.png' -s -e 'mv $f ~/screenshots/'")) + (interactive "sScreenshot filename: ") + (let* ((path (f-join "~/screenshots" + (format "%s-%d.png" + (if (string-empty-p filename) "shot" filename) + (time-convert nil 'integer))))) + (shell-command (format "maim --select %s" path)) + (message "Wrote screenshot to %s" path))) (defun graph-unread-mails () "Create a bar chart of unread mails based on notmuch tags. @@ -296,10 +258,11 @@ the GPG agent correctly." (defun find-cargo-project (dir) "Attempt to find the current project in `project-find-functions' by looking for a `Cargo.toml' file." - (unless (equal "/" dir) - (if (f-exists-p (f-join dir "Cargo.toml")) - (cons 'transient dir) - (find-cargo-project (f-parent dir))))) + (when dir + (unless (equal "/" dir) + (if (f-exists-p (f-join dir "Cargo.toml")) + (cons 'transient dir) + (find-cargo-project (f-parent dir)))))) (add-to-list 'project-find-functions #'find-cargo-project) @@ -310,45 +273,14 @@ by looking for a `Cargo.toml' file." (magit-read-file-from-rev "HEAD" "Find file") #'pop-to-buffer-same-window)) -(defun songwhip--handle-result (status &optional cbargs) - ;; TODO(tazjin): Inspect status, which looks different in practice - ;; than the manual claims. - (if-let* ((response (json-parse-string - (buffer-substring url-http-end-of-headers (point-max)))) - (sw-path (ht-get* response "data" "path")) - (link (format "https://songwhip.com/%s" sw-path)) - (select-enable-clipboard t)) - (progn - (kill-new link) - (message "Copied Songwhip link (%s)" link)) - (warn "Something went wrong while retrieving Songwhip link!") - ;; For debug purposes, the buffer is persisted in this case. - (setq songwhip--debug-buffer (current-buffer)))) - -(defun songwhip-lookup-url (url) - "Look up URL on Songwhip and copy the resulting link to the clipboard." - (interactive "sEnter source URL: ") - (let ((songwhip-url "https://songwhip.com/api/") - (url-request-method "POST") - (url-request-extra-headers '(("Content-Type" . "application/json"))) - (url-request-data - (json-serialize `((country . "GB") - (url . ,url))))) - (url-retrieve "https://songwhip.com/api/" #'songwhip--handle-result nil t t) - (message "Requesting Songwhip URL ... please hold the line."))) - -(defun rg-in-project (&optional prefix) - "Interactively call ripgrep in the current project, or fall - back to ripgrep default behaviour if prefix is set." - (interactive "P") - (counsel-rg nil (unless prefix - (if-let ((pr (project-current))) - (project-root pr))))) - -(defun zoxide-open-magit () - "Query Zoxide for paths and open magit in the result." +(defun zoxide-open-project () + "Query Zoxide for paths, and open the result as appropriate (magit or dired)." (interactive) - (zoxide-open-with nil #'magit-status-setup-buffer)) + (zoxide-open-with + nil + (lambda (path) + (condition-case err (magit-status-setup-buffer path) + (magit-outside-git-repo (dired path)))))) (defun toggle-nix-test-and-exp () "Switch between the .nix and .exp file in a Tvix/Nix test." @@ -361,4 +293,60 @@ by looking for a `Cargo.toml' file." (error "Not a .nix/.exp file!"))))) (find-file other))) +(defun reliably-switch-buffer () + "Reliably and interactively switch buffers, without ending up in a +situation where the buffer was renamed during selection and an +empty new buffer is created. + +This is done by, in contrast to most buffer-switching functions, +retaining a list of the buffer *objects* and their associated +names, instead of only their names (which might change)." + + (interactive) + (let* ((buffers (seq-map (lambda (b) (cons (buffer-name b) b)) + (seq-filter (lambda (b) (not (string-prefix-p " " (buffer-name b)))) + (buffer-list)))) + + ;; Annotate buffers that display remote files. I frequently + ;; want to see it, because I might have identically named + ;; files open locally and remotely at the same time, and it + ;; helps with differentiating them. + (completion-extra-properties + '(:annotation-function + (lambda (name) + (if-let* ((file (buffer-file-name (cdr (assoc name buffers)))) + (remote (file-remote-p file))) + (format " [%s]" remote))))) + + (name (completing-read "Switch to buffer: " (seq-map #'car buffers))) + (selected (or (cdr (assoc name buffers)) + ;; Allow users to manually select invisible buffers ... + (get-buffer name)))) + (switch-to-buffer (or selected name) nil 't))) + +(defun run-xdg-app () + "Use `//users/tazjin/gio-list-apps' to retrieve a list of +installed (and visible) XDG apps, and let users launch them." + (interactive) + (let* ((apps (taz-list-xdg-apps)) + + ;; Display the command that will be run as an annotation + (completion-extra-properties + '(:annotation-function (lambda (app) (format " [%s]" (cdr (assoc app apps))))))) + + (run-external-command--handler (cdr (assoc (completing-read "App: " apps nil t) apps))))) + +(defun advice-remove-all (sym) + "Remove all advices from symbol SYM." + (interactive "aFunction symbol: ") + (advice-mapc (lambda (advice _props) (advice-remove sym advice)) sym)) + +(defun M-x-always-same-window () + "Run `execute-extended-command', but ensure that whatever it does +always opens in the same window in which the command was invoked." + (interactive) + (let ((display-buffer-overriding-action + '((display-buffer-same-window) . ((inhibit-same-window . nil))))) + (call-interactively #'execute-extended-command))) + (provide 'functions) diff --git a/users/tazjin/emacs/config/init.el b/users/tazjin/emacs/config/init.el index 7eb1a19a8e..ced3bf2ff8 100644 --- a/users/tazjin/emacs/config/init.el +++ b/users/tazjin/emacs/config/init.el @@ -10,23 +10,9 @@ (require 'use-package) (require 'seq) -;; TODO(tazjin): Figure out what's up with vc. -;; -;; Leaving vc enabled breaks all find-file operations with messages -;; about .git folders being absent, but in random places. -(require 'vc) -(setq vc-handled-backends nil) - (package-initialize) ;; Initialise all packages installed via Nix. -;; -;; TODO: Generate this section in Nix for all packages that do not -;; require special configuration. - -;; -;; Packages providing generic functionality. -;; (use-package ace-window :bind (("C-x o" . ace-window)) @@ -43,13 +29,10 @@ (use-package browse-kill-ring) -(use-package company - :hook ((prog-mode . company-mode)) - :config (setq company-tooltip-align-annotations t)) - -(use-package counsel - :after (ivy) - :config (counsel-mode 1)) +(use-package consult + :bind + ("C-c r g" . consult-ripgrep) + ("C-s" . consult-line)) (use-package dash) (use-package gruber-darker-theme) @@ -59,39 +42,11 @@ (eglot-autoshutdown t) (eglot-send-changes-idle-time 0.3)) -(use-package elfeed - :config - (setq elfeed-feeds - '("https://lobste.rs/rss" - "https://www.anti-spiegel.ru/feed/" - "https://www.reddit.com/r/lockdownskepticism/.rss" - "https://www.reddit.com/r/rust/.rss" - "https://news.ycombinator.com/rss" - ("https://xkcd.com/atom.xml" media) - - ;; vlogcreations - ("https://www.youtube.com/feeds/videos.xml?channel_id=UCR0VLWitB2xM4q7tjkoJUPw" media) - ))) - (use-package ht) (use-package hydra) (use-package idle-highlight-mode :hook ((prog-mode . idle-highlight-mode))) -(use-package ivy - :config - (ivy-mode 1) - (setq enable-recursive-minibuffers t) - (setq ivy-use-virtual-buffers t)) - -(use-package ivy-prescient - :after (ivy prescient) - :config - (ivy-prescient-mode) - ;; Fixes an issue with how regexes are passed to ripgrep from counsel, - ;; see raxod502/prescient.el#43 - (setf (alist-get 'counsel-rg ivy-re-builders-alist) #'ivy--regex-plus)) - (use-package multiple-cursors) (use-package notmuch @@ -109,19 +64,14 @@ (pinentry-start)) (use-package prescient - :after (ivy counsel) - :config (prescient-persist-mode)) + :config + (prescient-persist-mode) + (setq completion-styles '(basic prescient))) (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) (use-package rainbow-mode) (use-package s) (use-package string-edit-at-point) - -(use-package swiper - :after (counsel ivy) - :bind (("C-s" . swiper))) - -(use-package telephone-line) ;; configuration happens outside of use-package (use-package term-switcher) (use-package undo-tree @@ -144,11 +94,9 @@ (use-package restclient) (use-package vterm - :config (progn - (setq vterm-shell "fish") - (setq vterm-exit-functions - (lambda (&rest _) (kill-buffer (current-buffer)))) - (setq vterm-kill-buffer-on-exit t))) + :custom + (vterm-shell "fish") + (vterm-kill-buffer-on-exit t)) ;; vterm removed the ability to set a custom title generator function ;; via the public API, so this overrides its private title generation @@ -169,7 +117,7 @@ (cargo-process-mode . visual-line-mode)) :bind (:map cargo-mode-map ("C-c C-c C-l" . ignore))) -(use-package dockerfile-mode) +(use-package dockerfile-ts-mode) (use-package erlang :hook ((erlang-mode . (lambda () @@ -189,9 +137,7 @@ (use-package ielm :hook ((inferior-emacs-lisp-mode . (lambda () - (paredit-mode) - (rainbow-delimiters-mode-enable) - (company-mode))))) + (rainbow-delimiters-mode-enable))))) (use-package jq-mode :config (add-to-list 'auto-mode-alist '("\\.jq\\'" . jq-mode))) @@ -200,8 +146,6 @@ :hook ((kotlin-mode . (lambda () (setq indent-line-function #'indent-relative))))) -(use-package lsp-mode) - (use-package markdown-mode :config (add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode)) @@ -220,22 +164,34 @@ (use-package sly :hook ((sly-mrepl-mode . (lambda () (paredit-mode) - (rainbow-delimiters-mode-enable) - (company-mode)))) + (rainbow-delimiters-mode-enable)))) :config (setq common-lisp-hyperspec-root "file:///home/tazjin/docs/lisp/")) (use-package telega - :bind (:map global-map ("s-t" . telega)) - :config (telega-mode-line-mode 1)) + :bind (:map global-map ("s-c" . (lambda (p) (interactive "P") + (if p (call-interactively #'telega-chat-with) + (telega)))) + :map telega-chat-button-map ("a" . ignore)) + :config (telega-mode-line-mode 1) + :custom + (telega-emoji-use-images nil) + (telega-completing-read-function #'completing-read)) (use-package terraform-mode) -(use-package toml-mode) +(use-package toml-ts-mode) + +(use-package treecrumbs + :hook ((yaml-ts-mode . treecrumbs-mode))) (use-package tvl) +(use-package vertico + :config + (vertico-mode)) + (use-package web-mode) -(use-package yaml-mode) +(use-package yaml-ts-mode) (use-package zoxide) (use-package passively @@ -275,7 +231,7 @@ ;; The way this will work for now is that Emacs will *write* ;; configuration to the file tracked in my repository, while not ;; actually *reading* it from there (unless Emacs is rebuilt). -(setq custom-file (expand-file-name "~/depot/tools/emacs/config/custom.el")) +(setq custom-file (f-join depot-path "users" "tazjin" "emacs" "config" "custom.el")) (load-library "custom") (defvar home-dir (expand-file-name "~")) @@ -290,10 +246,8 @@ look-and-feel functions settings - modes bindings eshell-setup)) -(telephone-line-setup) (ace-window-display-mode) ;; If a local configuration library exists, it should be loaded. diff --git a/users/tazjin/emacs/config/look-and-feel.el b/users/tazjin/emacs/config/look-and-feel.el index 72665d00c6..b771b4cd03 100644 --- a/users/tazjin/emacs/config/look-and-feel.el +++ b/users/tazjin/emacs/config/look-and-feel.el @@ -11,9 +11,6 @@ (setq ring-bell-function 'ignore) (setq initial-scratch-message "") -;; Remember layout changes -(winner-mode 1) - ;; Usually emacs will run as a proper GUI application, in which case a few ;; extra settings are nice-to-have: (when window-system @@ -22,69 +19,39 @@ (blink-cursor-mode -1)) ;; Configure Emacs fonts. -(let ((font (if (equal "frog" (s-trim (shell-command-to-string "hostname"))) - ;; For unclear reasons, frog refuses to render the - ;; regular font weight - everything ends up bold, - ;; which makes it hard to distinguish e.g. read/unread - ;; emails. - ;; - ;; Semi-bold looks a little different than on vauxhall - ;; and other machines, but it's alright. - (format "JetBrains Mono Semi Light-%d" 12) - (format "JetBrains Mono-%d" 12)))) +(let ((font (format "JetBrains Mono-%d" 12))) (setq default-frame-alist `((font . ,font))) (set-frame-font font t t)) -;; Configure telephone-line -(defun telephone-misc-if-last-window () - "Renders the mode-line-misc-info string for display in the - mode-line if the currently active window is the last one in the - frame. - - The idea is to not display information like the current time, - load, battery levels on all buffers." - - (when (bottom-right-window-p) - (telephone-line-raw mode-line-misc-info t))) - -(defun telephone-line-setup () - (telephone-line-defsegment telephone-line-last-window-segment () - (telephone-misc-if-last-window)) - - ;; Display the current EXWM workspace index in the mode-line - (telephone-line-defsegment telephone-line-exwm-workspace-index () - (when (bottom-right-window-p) - (format "[%s]" exwm-workspace-current-index))) - - ;; Define a highlight font for ~ important ~ information in the last - ;; window. - (defface special-highlight '((t (:foreground "white" :background "#5f627f"))) "") - (add-to-list 'telephone-line-faces - '(highlight . (special-highlight . special-highlight))) - - (setq telephone-line-lhs - '((nil . (telephone-line-position-segment)) - (accent . (telephone-line-buffer-segment)))) - - (setq telephone-line-rhs - '((accent . (telephone-line-major-mode-segment)) - (nil . (telephone-line-last-window-segment - telephone-line-exwm-workspace-index)) - - ;; TODO(tazjin): lets not do this particular thing while I - ;; don't actually run notmuch, there are too many things - ;; that have a dependency on the modeline drawing correctly - ;; (including randr operations!) - ;; - ;; (highlight . (telephone-line-notmuch-counts)) - )) - - (setq telephone-line-primary-left-separator 'telephone-line-tan-left - telephone-line-primary-right-separator 'telephone-line-tan-right - telephone-line-secondary-left-separator 'telephone-line-tan-hollow-left - telephone-line-secondary-right-separator 'telephone-line-tan-hollow-right) - - (telephone-line-mode 1)) +;; Configure the modeline + +;; Implements a mode-line warning if there are any logged in TTY +;; sessions apart from the graphical one. +;; +;; The status is only updated once every 30 seconds, as it requires +;; shelling out to some commands (for now). +(defun list-tty-sessions () + "List all logged in tty sessions, except tty7 (graphical)" + (let ((command "who | awk '{print $2}' | grep -v tty7")) + (-filter (lambda (s) (not (string-empty-p s))) + (s-lines + (s-trim (let ((default-directory "/")) + (shell-command-to-string command))))))) + +(defvar cached-tty-sessions (cons (time-convert nil 'integer) (list-tty-sessions)) + "Cached TTY session value to avoid running the command too often.") + +;; TODO(tazjin): add this to the modeline + +(defun get-cached-tty-sessions () + (let ((time )) + (when (< 30 + (- (time-convert nil 'integer) + (car cached-tty-sessions))) + (setq cached-tty-sessions + (cons (time-convert nil 'integer) (list-tty-sessions))))) + + (cdr cached-tty-sessions)) ;; Auto refresh buffers (global-auto-revert-mode 1) diff --git a/users/tazjin/emacs/config/mail-setup.el b/users/tazjin/emacs/config/mail-setup.el index 7fbece1b10..7352c8ba10 100644 --- a/users/tazjin/emacs/config/mail-setup.el +++ b/users/tazjin/emacs/config/mail-setup.el @@ -1,8 +1,6 @@ (require 'notmuch) -(require 'counsel-notmuch) ;; (global-set-key (kbd "C-c m") 'notmuch-hello) -;; (global-set-key (kbd "C-c C-m") 'counsel-notmuch) ;; (global-set-key (kbd "C-c C-e n") 'notmuch-mua-new-mail) (setq notmuch-cache-dir (format "%s/.cache/notmuch" (getenv "HOME"))) @@ -51,7 +49,7 @@ ;; handle that gracefully. (define-key notmuch-message-mode-map (kbd "C-x C-s") #'ignore) -;; Define a telephone-line segment for displaying the count of unread, +;; Define a mode-line segment for displaying the count of unread, ;; important mails in the last window's mode-line: (defvar *last-notmuch-count-redraw* 0) (defvar *current-notmuch-count* nil) @@ -76,10 +74,6 @@ (not (equal *current-notmuch-count* "I: 0; D: 0"))) *current-notmuch-count*)) -(telephone-line-defsegment telephone-line-notmuch-counts () - "This segment displays the count of unread notmuch messages in - the last window's mode-line (if unread messages are present)." - - (update-display-notmuch-counts)) +;; TODO(tazjin): re-add this segment to the modeline (provide 'mail-setup) diff --git a/users/tazjin/emacs/config/modes.el b/users/tazjin/emacs/config/modes.el deleted file mode 100644 index 69fb523d0d..0000000000 --- a/users/tazjin/emacs/config/modes.el +++ /dev/null @@ -1,37 +0,0 @@ -;; Initializes modes I use. - -(add-hook 'prog-mode-hook 'esk-add-watchwords) -(add-hook 'prog-mode-hook 'hl-line-mode) - -;; Use auto-complete as completion at point -(defun set-auto-complete-as-completion-at-point-function () - (setq completion-at-point-functions '(auto-complete))) - -(add-hook 'auto-complete-mode-hook - 'set-auto-complete-as-completion-at-point-function) - -;; Enable rainbow-delimiters for all things programming -(add-hook 'prog-mode-hook 'rainbow-delimiters-mode) - -;; Enable Paredit & Company in Emacs Lisp mode -(add-hook 'emacs-lisp-mode-hook 'company-mode) - -;; Always highlight matching brackets -(show-paren-mode 1) - -;; Always auto-close parantheses and other pairs -(electric-pair-mode) - -;; Keep track of recent files -(recentf-mode) - -;; Easily navigate sillycased words -(global-subword-mode 1) - -;; Transparently open compressed files -(auto-compression-mode t) - -;; Configure go-mode for Go2 Alpha -(add-to-list 'auto-mode-alist '("\\.go2$" . go-mode)) - -(provide 'modes) diff --git a/users/tazjin/emacs/config/settings.el b/users/tazjin/emacs/config/settings.el index 8b15b6cda1..afe181b70b 100644 --- a/users/tazjin/emacs/config/settings.el +++ b/users/tazjin/emacs/config/settings.el @@ -19,6 +19,9 @@ ediff-split-window-function 'split-window-horizontally initial-major-mode 'emacs-lisp-mode) +(setq-default tab-width 4) +(setq-default fill-column 80) + (add-to-list 'safe-local-variable-values '(lexical-binding . t)) (add-to-list 'safe-local-variable-values '(whitespace-line-column . 80)) @@ -45,4 +48,45 @@ ;; Show time in 24h format (setq display-time-24hr-format t) +;; Use python-mode for Starlark files. +(add-to-list 'auto-mode-alist '("\\.star\\'" . python-mode)) + +;; Use cmake-mode for relevant files. +(add-to-list 'auto-mode-alist '("ya\\.make\\'" . cmake-ts-mode)) + +;; Use tree-sitter modes for various languages. +(setq major-mode-remap-alist + '((bash-mode . bash-ts-mode) + (c++-mode . c++-ts-mode) + (c-mode . c-ts-mode) + (c-or-c++-mode . c-or-c++-ts-mode) + (json-mode . json-ts-mode) + (python-mode . python-ts-mode) + (rust-mode . rust-ts-mode) + (toml-mode . toml-ts-mode) + (yaml-mode . yaml-ts-mode) + (go-mode . go-ts-mode) + (cmake-mode . cmake-ts-mode))) + +;; Visually highlight current line in programming buffers +(add-hook 'prog-mode-hook 'hl-line-mode) + +;; Enable rainbow-delimiters for all things programming +(add-hook 'prog-mode-hook 'rainbow-delimiters-mode) + +;; Always highlight matching brackets +(show-paren-mode 1) + +;; Always auto-close parantheses and other pairs +(electric-pair-mode) + +;; Keep track of recent files +(recentf-mode) + +;; Easily navigate sillycased words +(global-subword-mode 1) + +;; Transparently open compressed files +(auto-compression-mode t) + (provide 'settings) diff --git a/users/tazjin/emacs/default.nix b/users/tazjin/emacs/default.nix index 6dfb37bb7e..46843432f1 100644 --- a/users/tazjin/emacs/default.nix +++ b/users/tazjin/emacs/default.nix @@ -1,11 +1,12 @@ # This file builds an Emacs pre-configured with the packages I need # and my personal Emacs configuration. -{ lib, pkgs, ... }: +{ depot, lib, pkgs, ... }: pkgs.makeOverridable - ({ emacs ? pkgs.emacsNativeComp }: + ({ emacs ? pkgs.emacs29 }: let - emacsWithPackages = (pkgs.emacsPackagesFor emacs).emacsWithPackages; + emacsPackages = (pkgs.emacsPackagesFor emacs); + emacsWithPackages = emacsPackages.emacsWithPackages; # If switching telega versions, use this variable because it will # keep the version check, binary path and so on in sync. @@ -19,6 +20,30 @@ pkgs.makeOverridable identity = x: x; + # tree-sitter grammars for various ts-modes + customTreesitGrammars = emacs.pkgs.treesit-grammars.with-grammars (g: with g; [ + tree-sitter-bash + tree-sitter-c + tree-sitter-cmake + tree-sitter-cpp + tree-sitter-css + tree-sitter-dockerfile + tree-sitter-go + tree-sitter-gomod + tree-sitter-hcl + tree-sitter-html + tree-sitter-java + tree-sitter-json + tree-sitter-latex + tree-sitter-make + tree-sitter-nix + tree-sitter-python + tree-sitter-rust + tree-sitter-sql + tree-sitter-toml + tree-sitter-yaml + ]); + tazjinsEmacs = pkgfun: (emacsWithPackages (epkgs: pkgfun (with epkgs; [ ace-link ace-window @@ -27,21 +52,13 @@ pkgs.makeOverridable browse-kill-ring cargo clojure-mode - cmake-mode - company - counsel - counsel-notmuch - d-mode + consult deft direnv - dockerfile-mode - eglot - elfeed elixir-mode elm-mode erlang - exwm - flymake + depotExwm go-mode google-c-style gruber-darker-theme @@ -49,15 +66,12 @@ pkgs.makeOverridable ht hydra idle-highlight-mode - ivy - ivy-prescient + inspector jq-mode kotlin-mode - lsp-mode + kubernetes magit markdown-toc - meson-mode - multi-term multiple-cursors nginx-mode nix-mode @@ -65,37 +79,36 @@ pkgs.makeOverridable paredit password-store pinentry - polymode prescient protobuf-mode rainbow-delimiters rainbow-mode - refine request restclient rust-mode sly string-edit-at-point - swiper - telephone-line terraform-mode - toml-mode - transient undo-tree - use-package uuidgen + vertico vterm web-mode websocket which-key xelb - yaml-mode yasnippet zetteldeft zoxide + # experimental (not otherwise embedded in config yet) + orderless + corfu + eat + # Wonky stuff (currentTelega epkgs) + customTreesitGrammars # TODO(tazjin): how is this *supposed* to work?! # Custom depot packages (either ours, or overridden ones) tvlPackages.dottime @@ -103,7 +116,11 @@ pkgs.makeOverridable tvlPackages.passively tvlPackages.rcirc tvlPackages.term-switcher + tvlPackages.treecrumbs tvlPackages.tvl + + # Dynamic/native modules + depot.users.tazjin.gio-list-apps ]))); # Tired of telega.el runtime breakages through tdlib @@ -138,10 +155,18 @@ pkgs.makeOverridable --no-site-lisp \ --no-init-file \ --directory ${./config} ${if l != null then "--directory ${l}" else ""} \ + --eval "(add-to-list 'treesit-extra-load-path \"${customTreesitGrammars}/lib\")" \ --eval "(require 'init)" $@ '').overrideAttrs (_: { passthru = { + # Expose original Emacs used for my configuration. + inherit emacs; + + # Expose the pure emacs with all packages. + inherit emacsPackages; + emacsWithPackages = tazjinsEmacs f; + # Call overrideEmacs with a function (pkgs -> pkgs) to modify the # packages that should be included in this Emacs distribution. overrideEmacs = f': self l f'; @@ -150,21 +175,6 @@ pkgs.makeOverridable # `local.el` which provides local system configuration. withLocalConfig = confDir: self confDir f; - # Build a derivation that uses the specified local Emacs (i.e. - # built outside of Nix) instead - withLocalEmacs = emacsBin: pkgs.writeShellScriptBin "tazjins-emacs" '' - export PATH="${emacsBinPath}:$PATH" - export EMACSLOADPATH="${(tazjinsEmacs f).deps}/share/emacs/site-lisp:" - exec ${emacsBin} \ - --debug-init \ - --no-site-file \ - --no-site-lisp \ - --no-init-file \ - --directory ${./config} \ - ${if l != null then "--directory ${l}" else ""} \ - --eval "(require 'init)" $@ - ''; - # Expose telega/tdlib version check as a target that is built in # CI. # diff --git a/users/tazjin/generator-example/.gitignore b/users/tazjin/generator-example/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/users/tazjin/generator-example/.gitignore @@ -0,0 +1 @@ +/target diff --git a/users/tazjin/generator-example/Cargo.lock b/users/tazjin/generator-example/Cargo.lock new file mode 100644 index 0000000000..a6f25ee394 --- /dev/null +++ b/users/tazjin/generator-example/Cargo.lock @@ -0,0 +1,124 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "genawaiter" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0" +dependencies = [ + "genawaiter-macro", + "genawaiter-proc-macro", + "proc-macro-hack", +] + +[[package]] +name = "genawaiter-macro" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc" + +[[package]] +name = "genawaiter-proc-macro" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738" +dependencies = [ + "proc-macro-error", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "generator-example" +version = "0.1.0" +dependencies = [ + "genawaiter", +] + +[[package]] +name = "proc-macro-error" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "syn-mid", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-mid" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa8e7560a164edb1621a55d18a0c59abf49d360f47aa7b821061dd7eea7fac9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/users/tazjin/generator-example/Cargo.toml b/users/tazjin/generator-example/Cargo.toml new file mode 100644 index 0000000000..faf313973f --- /dev/null +++ b/users/tazjin/generator-example/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "generator-example" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +genawaiter = "0.99.1" diff --git a/users/tazjin/generator-example/README.md b/users/tazjin/generator-example/README.md new file mode 100644 index 0000000000..0bec13ee9a --- /dev/null +++ b/users/tazjin/generator-example/README.md @@ -0,0 +1,11 @@ +generator-example +================= + +This is an experiment with the [`genawaiter`][] crate, to see if it +could be suitable for dealing with the execution flattening problem in +Tvix. + +It constructs a dummy example that is similar to some of the problems +we have in Tvix that require generator-like thunk forcing. + +[`genawaiter`]: https://docs.rs/genawaiter/latest/genawaiter/index.html diff --git a/users/tazjin/generator-example/src/main.rs b/users/tazjin/generator-example/src/main.rs new file mode 100644 index 0000000000..4aa931caf8 --- /dev/null +++ b/users/tazjin/generator-example/src/main.rs @@ -0,0 +1,115 @@ +use genawaiter::rc::{Co, Gen}; +use std::cell::RefCell; +use std::future::Future; +use std::pin::Pin; +use std::rc::Rc; + +#[derive(Debug)] +enum ValueRepr { + Int(i64), + Thunk((i64, i64)), +} + +#[derive(Clone, Debug)] +struct Value(Rc<RefCell<ValueRepr>>); + +impl Value { + fn force(&self) { + let mut inner = self.0.borrow_mut(); + match *inner { + ValueRepr::Int(_) => return, + ValueRepr::Thunk((a, b)) => { + *inner = ValueRepr::Int(a + b); + } + } + } + + fn is_forced(&self) -> bool { + matches!(*self.0.borrow(), ValueRepr::Int(_)) + } + + fn int(&self) -> i64 { + match *self.0.borrow() { + ValueRepr::Int(i) => i, + ValueRepr::Thunk(_) => panic!("unforced thunk!"), + } + } +} + +impl From<i64> for Value { + fn from(value: i64) -> Self { + Value(Rc::new(RefCell::new(ValueRepr::Int(value)))) + } +} + +impl From<(i64, i64)> for Value { + fn from(value: (i64, i64)) -> Self { + Value(Rc::new(RefCell::new(ValueRepr::Thunk(value)))) + } +} + +async fn list_maker(values: Vec<Value>, co: Co<Value>) -> Vec<i64> { + let mut output: Vec<i64> = vec![]; + + for value in values { + if !value.is_forced() { + co.yield_(value.clone()).await; + } + + output.push(value.int()); + } + + output +} + +async fn list_reverser(values: Vec<Value>, co: Co<Value>) -> Vec<i64> { + let mut output = list_maker(values, co).await; + output.reverse(); + output +} + +struct Frame { + gen: Gen<Value, (), Pin<Box<dyn Future<Output = Vec<i64>>>>>, +} + +fn pin_future( + f: impl Future<Output = Vec<i64>> + 'static, +) -> Pin<Box<dyn Future<Output = Vec<i64>>>> { + Box::pin(f) +} + +fn main() { + let mut frames: Vec<Frame> = vec![]; + + let values: Vec<Value> = vec![ + 42.into(), + (12, 54).into(), + 4.into(), + (40, 2).into(), + 2.into(), + ]; + let second = values.clone(); + + frames.push(Frame { + gen: Gen::new(|co| pin_future(list_maker(values, co))), + }); + + frames.push(Frame { + gen: Gen::new(|co| pin_future(list_reverser(second, co))), + }); + + for (idx, mut frame) in frames.into_iter().enumerate() { + loop { + match frame.gen.resume() { + genawaiter::GeneratorState::Yielded(val) => { + println!("yielded {:?} in frame {}", val, idx); + val.force(); + } + genawaiter::GeneratorState::Complete(list) => { + println!("result {}: {:?}", idx, list); + break; + } + } + } + } +} diff --git a/users/tazjin/gio-list-apps/.gitignore b/users/tazjin/gio-list-apps/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/users/tazjin/gio-list-apps/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/users/tazjin/gio-list-apps/Cargo.lock b/users/tazjin/gio-list-apps/Cargo.lock new file mode 100644 index 0000000000..b475b35a6c --- /dev/null +++ b/users/tazjin/gio-list-apps/Cargo.lock @@ -0,0 +1,616 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "cfg-expr" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "emacs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6797a940189d353de79bec32abe717aeeecd79a08236e84404c888354e040665" +dependencies = [ + "anyhow", + "ctor", + "emacs-macros", + "emacs_module", + "once_cell", + "rustc_version", + "thiserror", +] + +[[package]] +name = "emacs-macros" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69656fdfe7c2608b87164964db848b5c3795de7302e3130cce7131552c6be161" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "emacs_module" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3067bc974045ed2c6db333bd4fc30d3bdaafa6421a9a889fa7b2826b6f7f2fa" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gio" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7884cba6b1c5db1607d970cadf44b14a43913d42bc68766eea6a5e2fe0891524" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-list-apps" +version = "0.1.0" +dependencies = [ + "emacs", + "gio", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331156127e8166dd815cf8d2db3a5beb492610c716c03ee6db4f2d07092af0a7" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179643c50bf28d20d2f6eacd2531a88f2f5d9747dd0b86b8af1e8bb5dd0de3c0" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "thiserror" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winnow" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +dependencies = [ + "memchr", +] diff --git a/users/tazjin/gio-list-apps/Cargo.toml b/users/tazjin/gio-list-apps/Cargo.toml new file mode 100644 index 0000000000..eb62d1fcaf --- /dev/null +++ b/users/tazjin/gio-list-apps/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "gio-list-apps" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +emacs = "0.18.0" +gio = "0.18.1" diff --git a/users/tazjin/gio-list-apps/default.nix b/users/tazjin/gio-list-apps/default.nix new file mode 100644 index 0000000000..c63f4dd487 --- /dev/null +++ b/users/tazjin/gio-list-apps/default.nix @@ -0,0 +1,14 @@ +{ depot, pkgs, lib, ... }: + +pkgs.rustPlatform.buildRustPackage { + name = "gio-list-apps"; + src = lib.cleanSource ./.; + cargoLock.lockFile = ./Cargo.lock; + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.gtk3 depot.users.tazjin.emacs.emacs ]; + + postInstall = '' + mkdir -p $out/share/emacs/site-lisp + ln -s $out/lib/libgio_list_apps.so $out/share/emacs/site-lisp/gio-list-apps.so + ''; +} diff --git a/users/tazjin/gio-list-apps/src/lib.rs b/users/tazjin/gio-list-apps/src/lib.rs new file mode 100644 index 0000000000..55eb8dc0be --- /dev/null +++ b/users/tazjin/gio-list-apps/src/lib.rs @@ -0,0 +1,31 @@ +use emacs::{defun, Env, IntoLisp, Result, Value}; +use gio::traits::AppInfoExt; +use gio::AppInfo; + +emacs::plugin_is_GPL_compatible!(); + +#[emacs::module(defun_prefix = "taz", mod_in_name = false)] +fn init(_: &Env) -> Result<()> { + Ok(()) +} + +/// Returns an alist of the currently available XDG applications (through their +/// `.desktop' shortcuts), and the command line parameters needed to start them. +/// +/// Hidden applications or applications without specified command-line +/// parameters are not included. +#[defun] +fn list_xdg_apps(env: &Env) -> Result<Value> { + let mut visible_apps: Vec<Value> = vec![]; + + for app in AppInfo::all().into_iter().filter(AppInfo::should_show) { + if let Some(cmd) = app + .commandline() + .and_then(|p| Some(p.to_str()?.to_string())) + { + visible_apps.push(env.cons(app.name().as_str().into_lisp(env)?, cmd.into_lisp(env)?)?); + } + } + + env.list(&visible_apps) +} diff --git a/users/tazjin/home/khamovnik.nix b/users/tazjin/home/khamovnik.nix new file mode 100644 index 0000000000..6bac67eb1c --- /dev/null +++ b/users/tazjin/home/khamovnik.nix @@ -0,0 +1,10 @@ +# Home manage configuration for zamalek. + +{ depot, pkgs, ... }: # readTree +{ config, lib, ... }: # home-manager + +{ + imports = [ + depot.users.tazjin.home.shared + ]; +} diff --git a/users/tazjin/home/persistence.nix b/users/tazjin/home/persistence.nix new file mode 100644 index 0000000000..9ea5ca8eb9 --- /dev/null +++ b/users/tazjin/home/persistence.nix @@ -0,0 +1,42 @@ +# Persistence configuration for machines with throw-away setups. + +{ depot, pkgs, ... }: # readTree +{ config, lib, ... }: # home-manager + +{ + imports = [ (depot.third_party.sources.impermanence + "/home-manager.nix") ]; + + home.persistence."/persist/tazjin/home" = { + allowOther = true; + + directories = [ + ".cargo" + ".config/audacity" + ".config/chromium" + ".config/google-chrome" + ".config/quassel-irc.org" + ".config/syncthing" + ".config/unity3d" + ".electrum" + ".gnupg" + ".local/share/audacity" + ".local/share/direnv" + ".local/share/fish" + ".local/share/keyrings" + ".local/share/zoxide" + ".mozilla/firefox" + ".password-store" + ".rustup" + ".ssh" + ".steam" + ".telega" + ".thunderbird" + "go" + "mail" + ]; + + files = [ + ".notmuch-config" + ]; + }; +} diff --git a/users/tazjin/home/shared.nix b/users/tazjin/home/shared.nix index e2d51b4b04..38d8add4ac 100644 --- a/users/tazjin/home/shared.nix +++ b/users/tazjin/home/shared.nix @@ -3,42 +3,15 @@ { depot, pkgs, ... }: # readTree { config, lib, ... }: # home-manager -{ - imports = [ (depot.third_party.sources.impermanence + "/home-manager.nix") ]; - - home.persistence."/persist/tazjin/home" = { - allowOther = true; - - directories = [ - ".cargo" - ".config/audacity" - ".config/google-chrome" - ".config/quassel-irc.org" - ".config/syncthing" - ".config/unity3d" - ".electrum" - ".gnupg" - ".local/share/audacity" - ".local/share/direnv" - ".local/share/fish" - ".local/share/keyrings" - ".local/share/zoxide" - ".mozilla/firefox" - ".password-store" - ".rustup" - ".ssh" - ".steam" - ".telega" - ".thunderbird" - "go" - "mail" - ]; - - files = [ - ".notmuch-config" - ]; - }; +let + # URL handler to open `tg://` URLs in telega.el + telega-launcher = pkgs.writeShellScriptBin "telega-launcher" '' + echo "Opening ''${1} in telega.el ..." + ${depot.users.tazjin.emacs.emacs}/bin/emacsclient -e "(telega-browse-url \"''${1}\")" + ''; +in +{ home.activation.screenshots = lib.hm.dag.entryAnywhere '' $DRY_RUN_CMD mkdir -p $HOME/screenshots ''; @@ -57,6 +30,10 @@ programs.fish = { enable = true; interactiveShellInit = '' + # emacs vterm integration + source (find '${pkgs.emacsPackages.vterm}' -name 'emacs-vterm.fish') + + # z ${pkgs.zoxide}/bin/zoxide init fish | source ''; }; @@ -67,6 +44,27 @@ lockCmd = "${depot.users.tazjin.screenLock}/bin/tazjin-screen-lock"; }; + home.packages = [ telega-launcher ]; + + xdg.desktopEntries.telega-launcher = { + name = "Telega Launcher"; + exec = "${telega-launcher}/bin/telega-launcher"; + terminal = false; + mimeType = [ "x-scheme-handler/tg" ]; + }; + + xdg.mimeApps = { + enable = true; + defaultApplications = { + "x-scheme-handler/tg" = [ "telega-launcher.desktop" ]; + "text/html" = [ "firefox.desktop" ]; + "x-scheme-handler/http" = [ "firefox.desktop" ]; + "x-scheme-handler/https" = [ "firefox.desktop" ]; + "x-scheme-handler/about" = [ "firefox.desktop" ]; + "x-scheme-handler/unknown" = [ "firefox.desktop" ]; + }; + }; + services.picom = { enable = true; vSync = true; diff --git a/users/tazjin/home/tverskoy.nix b/users/tazjin/home/tverskoy.nix index d72734920e..6f1116340c 100644 --- a/users/tazjin/home/tverskoy.nix +++ b/users/tazjin/home/tverskoy.nix @@ -6,6 +6,7 @@ { imports = [ depot.users.tazjin.home.shared + depot.users.tazjin.home.persistence ]; home.persistence."/persist/tazjin/home" = { diff --git a/users/tazjin/home/zamalek.nix b/users/tazjin/home/zamalek.nix index 6bac67eb1c..d24de945bb 100644 --- a/users/tazjin/home/zamalek.nix +++ b/users/tazjin/home/zamalek.nix @@ -6,5 +6,6 @@ { imports = [ depot.users.tazjin.home.shared + depot.users.tazjin.home.persistence ]; } diff --git a/users/tazjin/homepage/default.nix b/users/tazjin/homepage/default.nix index 15f4d787c0..b46f9d4917 100644 --- a/users/tazjin/homepage/default.nix +++ b/users/tazjin/homepage/default.nix @@ -15,13 +15,18 @@ let inherit (pkgs) writeFile runCommand; # The different types of entries on the homepage. - entryClass = enum "entryClass" [ "blog" "project" "misc" ]; + entryClass = enum "entryClass" [ + "blog" + "project" + "note" + "misc" + ]; # The definition of a single entry. entry = struct "entry" { class = entryClass; - title = string; - url = string; + title = option string; + url = option string; date = int; # epoch description = option string; }; @@ -33,28 +38,42 @@ let title = post.title; url = "/blog/${post.key}"; date = post.date; + description = post.description or "Blog post from ${formatDate post.date}"; }); formatDate = defun [ int string ] (date: readFile (runCommand "date" { } '' - date --date='@${toString date}' '+%Y-%m-%d' > $out + date --date='@${toString date}' '+%Y-%m-%d' | tr -d '\n' > $out '')); - formatEntryDate = defun [ entry string ] (entry: entryClass.match entry.class { - blog = "Blog post from ${formatDate entry.date}"; - project = "Project from ${formatDate entry.date}"; - misc = "Posted on ${formatDate entry.date}"; - }); + entryUrl = defun [ entry string ] (entry: + if entry.class == "note" + then "#${toString entry.date}" + else entry.url + ); + + hasDescription = defun [ entry bool ] (entry: + ((entry ? description) && (entry.description != null)) + ); + + entryTitle = defun [ entry string ] (entry: + let + optionalColon = lib.optionalString (hasDescription entry) ":"; + titleText = + if (!(entry ? title) && (entry.class == "note")) + then "[${formatDate entry.date}]" + else lib.optionalString (entry ? title) ((escape entry.title) + optionalColon); + in + lib.optionalString (titleText != "") + ''<span class="entry-title ${entry.class}">${titleText}</span>'' + ); entryToDiv = defun [ entry string ] (entry: '' - <a href="${entry.url}" class="entry ${entry.class}"> - <div> - <p class="entry-title">${escape entry.title}</p> - ${ - lib.optionalString ((entry ? description) && (entry.description != null)) - "<p class=\"entry-description\">${escape entry.description}</p>" - } - <p class="entry-date">${formatEntryDate entry}</p> - </div> + <a href="${entryUrl entry}" id="${toString entry.date}" class="entry"> + ${entryTitle entry} + ${ + lib.optionalString (hasDescription entry) + "<span class=\"entry-description\">${escape entry.description}</span>" + } </a> ''); diff --git a/users/tazjin/homepage/entries.nix b/users/tazjin/homepage/entries.nix index 9e43516e53..0e98c073ef 100644 --- a/users/tazjin/homepage/entries.nix +++ b/users/tazjin/homepage/entries.nix @@ -1,12 +1,27 @@ +let + note = date: description: { + class = "note"; + inherit description date; + }; +in [ { + class = "project"; + title = "VolgaSprint - Nix hacking in Kazan"; + url = "https://volgasprint.org/"; + date = 1712307024; + description = '' + Hacking on Nix projects for a week in Kazan, Russia, in August + 2024. Come join us! + ''; + } + { class = "misc"; title = "@tazlog on Telegram"; url = "https://t.me/tazlog"; date = 1643321164; description = '' - My new channel on Telegram, for occasional updates smaller (and - more frequent) than what ends up being posted here. + My Telegram channel with occasional random life updates and musings. ''; } { @@ -15,8 +30,7 @@ url = "https://changelog.com/shipit/37"; date = 1641819600; description = '' - Episode #37 of Ship It!, a podcast about systems, featuring me. - We talk about TVL, Nix, monorepos and related things. + Podcast episode about TVL, Nix, monorepos and all sorts of related things. ''; } { @@ -24,9 +38,7 @@ title = "Tvix"; url = "https://tvl.fyi/blog/rewriting-nix"; date = 1638381387; - description = '' - TVL is rewriting Nix with funding from NLNet. - ''; + description = "TVL is rewriting Nix with funding from NLNet."; } { class = "misc"; @@ -34,8 +46,7 @@ url = "https://www.youtube.com/watch?v=P-2P3MSZrBM"; date = 1594594800; description = '' - A fascinating, mind-bending interview by Lex Fridman with Joscha - Bach about the Nature of the Universe. + Mind-bending discussion with philosopher Joscha Bach. ''; } { @@ -43,7 +54,7 @@ title = "The Virus Lounge"; url = "https://tvl.fyi"; date = 1587435629; - description = "A community around Nix, monorepos, build tooling and the like!"; + description = "A community around Nix, monorepos, build tooling and more!"; } { class = "project"; @@ -71,7 +82,7 @@ title = "dottime"; url = "https://dotti.me/"; date = 1560898800; - description = "A universal convention for conveying time (by edef <3)"; + description = "A universal convention for conveying time"; } { class = "project"; @@ -86,18 +97,63 @@ url = "https://principiadiscordia.com/book/1.php"; date = 1495494000; description = '' - The Principia is a short book I read as a child, and didn't - understand until much later. It shaped much of my world view. + A short book about everything that everyone should read. ''; } { class = "misc"; - title = "This Week in Virology"; - url = "http://www.microbe.tv/twiv/"; - date = 1585517557; - description = '' - Podcast with high-quality information about virology, - epidemiology and so on. Highly relevant to COVID19. - ''; + title = "Nix — не только пакетный менеджер"; + date = 1663923600; + url = "https://www.youtube.com/watch?v=0Lhahzs-Wos"; + description = "Двухчасовой (!) разговор с введением в Nix, NixOS и так далее"; + } + { + class = "project"; + title = "yandex-cloud-rs"; + date = 1650877200; + url = "https://docs.rs/yandex-cloud"; + description = "Простой SDK на Rust для работы с API Yandex Cloud."; + } + { + class = "project"; + title = "nix-1p"; + date = 1564650000; + url = "https://code.tvl.fyi/about/nix/nix-1p"; + description = "A (more or less) one-page introduction to the Nix language."; + } + { + class = "misc"; + title = "Ставим NixOS!"; + date = 1678784400; + url = "https://progmsk.timepad.ru/event/2358560/"; + description = "Встреча в undef.space для помощи в начале работы с Nix/NixOS"; + } + { + class = "misc"; + title = "Tvix - September '22"; + date = 1662973200; + url = "https://tvl.fyi/blog/tvix-status-september-22"; + description = "Tvix update blog post over on TVL"; + } + { + class = "project"; + title = "Tvixbolt"; + date = 1667293200; + url = "https://bolt.tvix.dev/"; + description = "In-browser language evaluator for Nix, based on Tvix"; + } + { + class = "project"; + title = "ООО ТВЛ"; + date = 1609491600; + url = "https://tvl.su/ru/"; + description = "Официальный сайт моей компании по IT-консалтингу."; } + + # Notes. + (note 1676106000 "If you have a Huawei device that sometimes struggles on public Wi-Fi networks, try enabling MAC-address randomisation. Huawei devices often get pushed onto management networks!") + (note 1686868637 "I moved some of my pages (including this one) to a machine in my flat in Moscow. If you end up having access trouble because your ISP blocks Russian resources, please let me know.") + (note 1686868636 "Protip: Use the Reddit blackout to click the 'Logout' button, and never come back.") + (note 1486550941 "↓ I no longer recommend people to use this. Generate your configuration from a language like Nix instead.") + (note 1576800001 "↓ No longer just my projects, it's all of TVL! Go check it out.") ] diff --git a/users/tazjin/homepage/feed.nix b/users/tazjin/homepage/feed.nix index 09bc363414..8043d7ff30 100644 --- a/users/tazjin/homepage/feed.nix +++ b/users/tazjin/homepage/feed.nix @@ -4,7 +4,7 @@ with depot.nix.yants; let - inherit (builtins) map readFile; + inherit (builtins) filter map readFile; inherit (lib) max singleton; inherit (pkgs) writeText; inherit (depot.web) blog atom-feed; @@ -23,7 +23,7 @@ let }); allEntries = (with depot.users.tazjin.blog; map (blog.toFeedEntry config) posts) - ++ (map pageEntryToEntry pageEntries); + ++ (map pageEntryToEntry (filter (e: e.class != "note") pageEntries)); feed = { id = "https://tazj.in/"; diff --git a/users/tazjin/homepage/header.html b/users/tazjin/homepage/header.html index 5a22d9eb7b..320b5ded8c 100644 --- a/users/tazjin/homepage/header.html +++ b/users/tazjin/homepage/header.html @@ -3,6 +3,7 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content="tazjin's blog"> <link rel="stylesheet" type="text/css" href="static/tvl.css" media="all"> + <link rel="stylesheet" type="text/css" href="static/tazjin.css" media="all"> <link rel="icon" type="image/webp" href="/static/favicon.webp"> <link rel="alternate" type="application/atom+xml" href="/feed.atom"> <title>tazjin's interblag</title> @@ -15,22 +16,14 @@ <hr> </header> <div class="introduction"> - <p>Hi, I'm tazjin.</p> <p> - I spend a lot of my time hacking on the - <a class="dark-link" href="https://tvl.fyi">TVL</a> monorepo and - doing other computer-related things. Follow me - on <a class="dark-link" href="https://t.me/tazlog">Telegram</a>, - via the feed here or (occasionally) catch me in-person - at <a href="https://undef.club/#about" class="dark-link"> - undef.club</a>. - </p> - <p> - Below is a collection of + Below are some of my <span class="project">projects</span>, <span class="blog">blog - posts</span> and some <span class="misc">random things</span> by - me or others. If you'd like to get in touch about anything, send - me a mail at mail@[this domain] or ping me on IRC. + posts</span>, <span class="note">notes</span> and some + other <span class="misc">random things</span>. If you'd like to + get in touch, email me at mail@[this domain] or ping me + on <a class="dark-link" href="https://tvl.fyi">TVL</a> IRC. </p> + <hr> </div> <div class="entry-container"> diff --git a/users/tazjin/homepage/static/tazjin.css b/users/tazjin/homepage/static/tazjin.css new file mode 100644 index 0000000000..f921b562ee --- /dev/null +++ b/users/tazjin/homepage/static/tazjin.css @@ -0,0 +1,57 @@ +/* Homepage styling */ + +.dark { + background-color: #181818; + color: #e4e4ef; +} + +.dark-link, .interblag-title { + color: #96a6c8; +} + + +.interblag-title { + text-decoration: none; +} + +.entry-container { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + justify-content: flex-start; +} + +.entry { + margin-top: 5px; + margin-bottom: 5px; + padding-left: 5px; + text-decoration: none; +} + +.entry:nth-child(odd) { + background: #282828; +} + +.entry-description { + color: #e4e4ef; +} + +.misc { + color: #73c936; + border-color: #73c936; +} + +.blog { + color: #268bd2; + border-color: #268bd2; +} + +.project { + color: #ff4f58; + border-color: #ff4f58; +} + +.note { + color: #ffdd33; + border-color: #ffdd33; +} diff --git a/users/tazjin/keys/default.nix b/users/tazjin/keys/default.nix index f15fcb69e8..16b232b094 100644 --- a/users/tazjin/keys/default.nix +++ b/users/tazjin/keys/default.nix @@ -7,4 +7,6 @@ in withAll { tverskoy_ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM1fGWz/gsq+ZeZXjvUrV+pBlanw1c3zJ9kLTax9FWQy tazjin@tverskoy"; zamalek_sk = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOAw3OaPAjnC6hArGYEmBoXhPf7aZdRGlDZcSqm6gbB8AAAABHNzaDo= tazjin@zamalek"; zamalek_ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDBRXeb8EuecLHP0bW4zuebXp4KRnXgJTZfeVWXQ1n1R tazjin@zamalek"; + khamovnik_yk = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPgOyR4rRM8IaVGgN2ZxGlKtd7GLYbxdRTRa3u9EhRNSkHAvRTN9sgw7mm0iPLnHChPy10anKV43vTaIm906Gm8="; + khamovnik_agenix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG4YSl5+DHQR3rOoBJLQfQ840U0CrYkByMKdzu/LDxoT tazjin@khamovnik"; } diff --git a/users/tazjin/kinesis/README.md b/users/tazjin/kinesis/README.md new file mode 100644 index 0000000000..7cd95a5e5f --- /dev/null +++ b/users/tazjin/kinesis/README.md @@ -0,0 +1,10 @@ +Kinesis configuration +===================== + +This folder backs up the configuration for my Kinesis keyboards. +Configuration is not mutually compatible between the Advantage 2 and +the Advantage 360, so they are stored in different folders and +(mostly) programmed on-board. + +I keep these around in case I get a new keyboard and want to bootstrap +it to behave the same way as the previous one. diff --git a/users/tazjin/kinesis/advantage2/qwerty.txt b/users/tazjin/kinesis/advantage2/qwerty.txt new file mode 100755 index 0000000000..624e809c22 --- /dev/null +++ b/users/tazjin/kinesis/advantage2/qwerty.txt @@ -0,0 +1,6 @@ +[caps]>[rwin] +[lctrl]>[lalt] +[delete]>[lctrl] +[rctrl]>[rwin] +{pup}>{-rwin}{b}{+rwin} +{pdown}>{-rwin}{f}{+rwin} diff --git a/users/tazjin/nix.svg b/users/tazjin/nix.svg index 4da795a436..d2ef7c81aa 100644 --- a/users/tazjin/nix.svg +++ b/users/tazjin/nix.svg @@ -33,7 +33,7 @@ id="lambda-4" href="#lambda-path" visibility="visible" - fill="#f8f8ff" /> + fill="#d52b1e" /> <use id="lambda-5" transform="rotate(60,407.11155,-715.78724)" @@ -45,6 +45,6 @@ id="lambda-6" href="#lambda-path" visibility="visible" - fill="#d52b1e" /> + fill="#f8f8ff" /> </g> </svg> diff --git a/users/tazjin/nixos/camden/default.nix b/users/tazjin/nixos/camden/default.nix index 7c700d43e3..130b51dd38 100644 --- a/users/tazjin/nixos/camden/default.nix +++ b/users/tazjin/nixos/camden/default.nix @@ -54,7 +54,7 @@ lib.fix (self: { efi.canTouchEfiVariables = true; }; - cleanTmpDir = true; + tmp.cleanOnBoot = true; }; fileSystems = { @@ -108,7 +108,7 @@ lib.fix (self: { programs.mosh.enable = true; fonts = { - fonts = [ pkgs.jetbrains-mono ]; + packages = [ pkgs.jetbrains-mono ]; fontconfig.defaultFonts.monospace = [ "JetBrains Mono" ]; }; @@ -163,7 +163,7 @@ lib.fix (self: { services.tailscale.enable = true; # Allow sudo-ing via the forwarded SSH agent. - security.pam.enableSSHAgentAuth = true; + security.pam.sshAgentAuth.enable = true; # NixOS 20.03 broke nginx and I can't be bothered to debug it # anymore, all solution attempts have failed, so here's a diff --git a/users/tazjin/nixos/default.nix b/users/tazjin/nixos/default.nix index b9cae51d7f..8f82c39ea1 100644 --- a/users/tazjin/nixos/default.nix +++ b/users/tazjin/nixos/default.nix @@ -5,6 +5,8 @@ in depot.nix.readTree.drvTargets { camdenSystem = systemFor depot.users.tazjin.nixos.camden; frogSystem = systemFor depot.users.tazjin.nixos.frog; tverskoySystem = systemFor depot.users.tazjin.nixos.tverskoy; - polyankaSystem = (depot.ops.nixos.nixosFor depot.users.tazjin.nixos.polyanka).system; zamalekSystem = systemFor depot.users.tazjin.nixos.zamalek; + koptevoRaw = depot.ops.nixos.nixosFor depot.users.tazjin.nixos.koptevo; + koptevoSystem = systemFor depot.users.tazjin.nixos.koptevo; + khamovnikSystem = systemFor depot.users.tazjin.nixos.khamovnik; } diff --git a/users/tazjin/nixos/frog/default.nix b/users/tazjin/nixos/frog/default.nix index 1400517eec..dfb6b46d5a 100644 --- a/users/tazjin/nixos/frog/default.nix +++ b/users/tazjin/nixos/frog/default.nix @@ -11,12 +11,8 @@ let }; in lib.fix (self: { - imports = [ - (depot.path.origSrc + "/ops/modules/v4l2loopback.nix") - ]; - boot = { - tmpOnTmpfs = true; + tmp.useTmpfs = true; kernelModules = [ "kvm-amd" ]; loader = { @@ -64,7 +60,6 @@ lib.fix (self: { nix.settings = { max-jobs = 48; substituters = [ "ssh://nix-ssh@whitby.tvl.fyi" ]; - trusted-public-keys = [ "cache.tvl.fyi:fd+9d1ceCPvDX/xVhcfv8nAa6njEhAGAEe+oGJDEeoc=" ]; }; networking = { @@ -111,7 +106,7 @@ lib.fix (self: { }; fonts = { - fonts = with pkgs; [ + packages = with pkgs; [ corefonts dejavu_fonts jetbrains-mono @@ -157,8 +152,8 @@ lib.fix (self: { services.xserver = { enable = true; - layout = "us"; - xkbOptions = "caps:super"; + xkb.layout = "us"; + xkb.options = "caps:super"; exportConfiguration = true; videoDrivers = [ "amdgpu" ]; displayManager = { @@ -222,13 +217,12 @@ lib.fix (self: { bat chromium clang-manpages - clang-tools_11 - clang_11 + clang-tools + clang curl direnv dnsutils emacs28 # mostly for emacsclient - exa fd file gdb @@ -262,7 +256,6 @@ lib.fix (self: { ripgrep rustup screen - scrot spotify tokei transmission diff --git a/users/tazjin/nixos/khamovnik/default.nix b/users/tazjin/nixos/khamovnik/default.nix new file mode 100644 index 0000000000..8ea925c90d --- /dev/null +++ b/users/tazjin/nixos/khamovnik/default.nix @@ -0,0 +1,133 @@ +# Yandex work laptop +# +# Some of the configuration for this machine is not public. +{ depot, lib, pkgs, ... }: + +config: +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); + usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); + private = /arc/junk/tazjin; + + zdevice = device: { + inherit device; + fsType = "zfs"; + }; +in +{ + imports = [ + (usermod "chromium.nix") + (usermod "desktop.nix") + (usermod "fonts.nix") + (usermod "home-config.nix") + (usermod "laptop.nix") + (usermod "physical.nix") + (pkgs.home-manager.src + "/nixos") + ] ++ (if (builtins.pathExists private) then [ + (private + "/nixos/yandex.nix") + (private + "/emacs/module.nix") + ] else [ ]); + + # from hardware-configuration.nix + boot = { + initrd.luks.devices."luks-9c3cd590-a648-450d-ae42-ed3859d4c717".device = + "/dev/disk/by-uuid/9c3cd590-a648-450d-ae42-ed3859d4c717"; + + initrd.availableKernelModules = [ + "xhci_pci" + "thunderbolt" + "ahci" + "nvme" + "usb_storage" + "sd_mod" + "rtsx_pci_sdmmc" + ]; + kernelModules = [ "kvm-intel" ]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/1f783029-c4f9-4192-b893-84f4f0c2a493"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/DD01-2B3E"; + fsType = "vfat"; + }; + }; + + swapDevices = [{ + device = "/dev/disk/by-uuid/9b9049c5-5975-441d-9ac6-2f9150775fd6"; + }]; + + tvl.cache.enable = true; + + networking.hostName = "khamovnik"; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + hardware.opengl.extraPackages = with pkgs; [ + intel-compute-runtime + intel-media-driver + intel-vaapi-driver + ]; + + # from generated configuration.nix + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Setup keyfile + boot.initrd.secrets = { + "/crypto_keyfile.bin" = null; + }; + + # Enable swap on luks + boot.initrd.luks.devices."luks-e9a4b4dc-ade2-45bf-8ed0-0ed5c4c392c9".device = "/dev/disk/by-uuid/e9a4b4dc-ade2-45bf-8ed0-0ed5c4c392c9"; + boot.initrd.luks.devices."luks-e9a4b4dc-ade2-45bf-8ed0-0ed5c4c392c9".keyFile = "/crypto_keyfile.bin"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "ru_RU.UTF-8"; + LC_IDENTIFICATION = "ru_RU.UTF-8"; + LC_MEASUREMENT = "ru_RU.UTF-8"; + LC_MONETARY = "ru_RU.UTF-8"; + LC_NAME = "ru_RU.UTF-8"; + LC_NUMERIC = "ru_RU.UTF-8"; + LC_PAPER = "ru_RU.UTF-8"; + LC_TELEPHONE = "ru_RU.UTF-8"; + LC_TIME = "ru_RU.UTF-8"; + }; + + # Enable sound with pipewire. + sound.enable = true; + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + + # Try to work around Intel CPU throttling bugs + services.throttled.enable = true; + + virtualisation.docker.enable = true; + + hardware.bluetooth.enable = true; + users.users.tazjin.extraGroups = [ "tss" ]; + + environment.systemPackages = with pkgs; [ + tdesktop + linuxPackages.perf + hotspot + protobuf + ]; + + system.stateVersion = "23.05"; # Did you read the comment? +} diff --git a/users/tazjin/nixos/koptevo/default.nix b/users/tazjin/nixos/koptevo/default.nix new file mode 100644 index 0000000000..ea8dfd4bd8 --- /dev/null +++ b/users/tazjin/nixos/koptevo/default.nix @@ -0,0 +1,187 @@ +# NUC in my closet. +_: # ignore readTree options + +{ config, depot, lib, pkgs, ... }: + +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); + usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); +in +{ + imports = [ + (mod "quassel.nix") + (mod "www/base.nix") + (mod "www/tazj.in.nix") + (usermod "airsonic.nix") + (usermod "geesefs.nix") + (usermod "predlozhnik.nix") + (usermod "tgsa.nix") + (usermod "miniflux.nix") + (depot.third_party.agenix.src + "/modules/age.nix") + ]; + + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + initrd.availableKernelModules = [ "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ]; + kernelModules = [ "kvm-intel" ]; + kernelParams = [ "nomodeset" ]; + }; + + nix.settings.trusted-users = [ "tazjin" ]; + + fileSystems = { + "/" = { + device = "rpool/root"; + fsType = "zfs"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/E214-E6B3"; + fsType = "vfat"; + }; + + "/var" = { + device = "rpool/var"; + fsType = "zfs"; + }; + + "/home" = { + device = "rpool/home"; + fsType = "zfs"; + }; + }; + + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + services.fwupd.enable = true; + + networking = { + hostName = "koptevo"; + hostId = "07bbbf4f"; + domain = "tazj.in"; + useDHCP = true; + firewall.enable = true; + firewall.allowedTCPPorts = [ 22 80 443 ]; + + wireless.enable = true; + wireless.networks."How do I computer fast?" = { + psk = "washyourface"; + }; + }; + + time.timeZone = "UTC"; + + security.acme.acceptTerms = true; + security.acme.defaults.email = lib.mkForce "acme@tazj.in"; + + programs.fish.enable = true; + + users.users.tazjin = { + isNormalUser = true; + extraGroups = [ "wheel" "docker" "systemd-journal" ]; + shell = pkgs.fish; + openssh.authorizedKeys.keys = depot.users.tazjin.keys.all; + }; + + age.secrets = + let + secretFile = name: depot.users.tazjin.secrets."${name}.age"; + in + { + tgsa-yandex.file = secretFile "tgsa-yandex"; + }; + + security.sudo.wheelNeedsPassword = false; + + services.openssh.enable = true; + + services.depot.quassel = { + enable = true; + acmeHost = "koptevo.tazj.in"; + bindAddresses = [ + "0.0.0.0" + ]; + }; + + services.tailscale = { + enable = true; + useRoutingFeatures = "server"; # for exit-node usage + }; + + # Automatically collect garbage from the Nix store. + services.depot.automatic-gc = { + enable = true; + interval = "daily"; + diskThreshold = 15; # GiB + maxFreed = 10; # GiB + preserveGenerations = "14d"; + }; + + services.nginx.virtualHosts."koptevo.tazj.in" = { + addSSL = true; + enableACME = true; + + extraConfig = '' + location = / { + return 302 https://at.tvl.fyi/?q=%2F%2Fusers%2Ftazjin%2Fnixos%2Fkoptevo%2Fdefault.nix; + } + ''; + }; + + # I don't use the podcast nor playlist feature, + # but I *have to* supply podcasts to gonic ... + systemd.tmpfiles.rules = [ + "d /tmp/fake-podcasts 0555 nobody nobody -" + "d /tmp/fake-playlists 0555 nobody nobody -" + ]; + + services.gonic = { + enable = true; + settings = { + listen-addr = "0.0.0.0:4747"; + scan-interval = 5; + scan-at-start-enabled = true; + podcast-path = [ "/tmp/fake-podcasts" ]; + playlists-path = [ "/tmp/fake-playlists" ]; + music-path = [ "/var/lib/geesefs/tazjins-files/music" ]; + }; + }; + + # hack to work around the strict sandboxing of the gonic module + # breaking DNS resolution + systemd.services.gonic.serviceConfig.BindReadOnlyPaths = [ + "-/etc/resolv.conf" + ]; + + # add a hard dependency on the FUSE mount + systemd.services.gonic.requires = [ "geesefs.service" ]; + + services.nginx.virtualHosts."music.tazj.in" = { + addSSL = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:4747"; + }; + }; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + curl + htop + jq + nmap + bat + emacs-nox + nano + wget + ]; + + programs.mtr.enable = true; + programs.mosh.enable = true; + zramSwap.enable = true; + + system.stateVersion = "23.05"; +} diff --git a/users/tazjin/nixos/modules/airsonic.nix b/users/tazjin/nixos/modules/airsonic.nix new file mode 100644 index 0000000000..815f183778 --- /dev/null +++ b/users/tazjin/nixos/modules/airsonic.nix @@ -0,0 +1,32 @@ +# airsonic is a decent, web-based player UI for subsonic +{ pkgs, ... }: + +let + env = builtins.toFile "env.js" '' + window.env = { + SERVER_URL: "https://music.tazj.in", + } + ''; + + airsonicDist = pkgs.fetchzip { + name = "airsonic-refix"; + + # from master CI @ f894d5eacebec2f47486f340c8610f446d4f64b3 + # https://github.com/tamland/airsonic-refix/actions/runs/6150155527 + url = "https://storage.yandexcloud.net/tazjin-public/airsonic-refix-f894d5ea.zip"; + sha256 = "02rnh9h7rh22wkghays389yddwbwg7sawmczdxdmjrcnkc7mq2jz"; + + stripRoot = false; + postFetch = "cp ${env} $out/env.js"; + }; +in +{ + services.nginx.virtualHosts."player.tazj.in" = { + enableACME = true; + forceSSL = true; + root = "${airsonicDist}"; + + # deal with SPA routing requirements + locations."/".extraConfig = "try_files $uri /index.html;"; + }; +} diff --git a/users/tazjin/nixos/modules/chromium.nix b/users/tazjin/nixos/modules/chromium.nix new file mode 100644 index 0000000000..22f1c8d362 --- /dev/null +++ b/users/tazjin/nixos/modules/chromium.nix @@ -0,0 +1,30 @@ +# Configure the Chromium browser with various useful things. +{ pkgs, ... }: + +{ + environment.systemPackages = [ + (pkgs.chromium.override { + enableWideVine = true; # DRM support (for Кинопоиск) + }) + ]; + + programs.chromium = { + enable = true; + homepageLocation = "about:blank"; + + extensions = [ + "dbepggeogbaibhgnhhndojpepiihcmeb" # Vimium + "cjpalhdlnbpafiamejdnhcphjbkeiagm" # uBlock Origin + "mohaicophfnifehkkkdbcejkflmgfkof" # nitter redirect + "lhdifindchogekmjooeiolmjdlheilae" # Huruf + ]; + + extraOpts = { + SpellcheckEnabled = true; + SpellcheckLanguage = [ + "ru" + "en-GB" + ]; + }; + }; +} diff --git a/users/tazjin/nixos/modules/desktop.nix b/users/tazjin/nixos/modules/desktop.nix index c78463386c..12a42b8faa 100644 --- a/users/tazjin/nixos/modules/desktop.nix +++ b/users/tazjin/nixos/modules/desktop.nix @@ -1,11 +1,12 @@ # EXWM and other desktop configuration. -{ depot, lib, pkgs, ... }: +{ config, depot, lib, pkgs, ... }: { services = { pipewire = { enable = true; alsa.enable = true; + alsa.support32Bit = true; pulse.enable = true; }; @@ -14,8 +15,8 @@ xserver = { enable = true; - layout = "us"; - xkbOptions = "caps:super"; + xkb.layout = "us"; + xkb.options = "caps:super"; libinput.enable = true; @@ -28,7 +29,7 @@ windowManager.session = lib.singleton { name = "exwm"; - start = "${depot.users.tazjin.emacs}/bin/tazjins-emacs"; + start = "${config.tazjin.emacs}/bin/tazjins-emacs --internal-border=0 --border-width=0"; }; }; }; @@ -40,6 +41,7 @@ QT_IM_MODULE = "xim"; CLUTTER_IM_MODULE = "xim"; EDITOR = "emacsclient"; + _JAVA_AWT_WM_NONREPARENTING = "1"; }; # Do not restart the display manager automatically diff --git a/users/tazjin/nixos/modules/fonts.nix b/users/tazjin/nixos/modules/fonts.nix index 3b4461056f..ee1b84e581 100644 --- a/users/tazjin/nixos/modules/fonts.nix +++ b/users/tazjin/nixos/modules/fonts.nix @@ -4,7 +4,7 @@ { fonts = { - fonts = with pkgs; [ + packages = with pkgs; [ corefonts dejavu_fonts jetbrains-mono diff --git a/users/tazjin/nixos/modules/geesefs.nix b/users/tazjin/nixos/modules/geesefs.nix new file mode 100644 index 0000000000..c45ee528f6 --- /dev/null +++ b/users/tazjin/nixos/modules/geesefs.nix @@ -0,0 +1,38 @@ +{ depot, pkgs, ... }: + +{ + imports = [ + (depot.third_party.agenix.src + "/modules/age.nix") + ]; + + age.secrets.geesefs-tazjins-files.file = depot.users.tazjin.secrets."geesefs-tazjins-files.age"; + programs.fuse.userAllowOther = true; + + systemd.services.geesefs = { + description = "geesefs @ tazjins-files"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.fuse ]; + + serviceConfig = { + # TODO: can't get fusermount to work for non-root users (e.g. DynamicUser) here, why? + + Restart = "always"; + LoadCredential = "geesefs-tazjins-files:/run/agenix/geesefs-tazjins-files"; + StateDirectory = "geesefs"; + ExecStartPre = "/run/wrappers/bin/umount -a -t fuse.geesefs"; + }; + + script = '' + set -u # bail out if systemd is misconfigured ... + set -x + + mkdir -p $STATE_DIRECTORY/tazjins-files $STATE_DIRECTORY/cache + + ${depot.third_party.geesefs}/bin/geesefs \ + -f -o allow_other \ + --cache $STATE_DIRECTORY/cache \ + --shared-config $CREDENTIALS_DIRECTORY/geesefs-tazjins-files \ + tazjins-files $STATE_DIRECTORY/tazjins-files + ''; + }; +} diff --git a/users/tazjin/nixos/modules/hidpi.nix b/users/tazjin/nixos/modules/hidpi.nix index 7fa3e41933..2ff61d499a 100644 --- a/users/tazjin/nixos/modules/hidpi.nix +++ b/users/tazjin/nixos/modules/hidpi.nix @@ -7,8 +7,10 @@ # screen settings to do conditional initialisation (mostly for Emacs). environment.variables.HIDPI_SCREEN = "true"; + # TODO(tazjin): this option has been removed and needs to be replaced + # by manual configuration: https://github.com/NixOS/nixpkgs/issues/222805 # Ensure a larger font size in early boot stage. - hardware.video.hidpi.enable = true; + # hardware.video.hidpi.enable = true; # Bump DPI across the board. # TODO(tazjin): This should actually be set per monitor, but I diff --git a/users/tazjin/nixos/modules/miniflux.nix b/users/tazjin/nixos/modules/miniflux.nix new file mode 100644 index 0000000000..72089bfb3d --- /dev/null +++ b/users/tazjin/nixos/modules/miniflux.nix @@ -0,0 +1,22 @@ +{ config, depot, lib, pkgs, ... }: + +{ + age.secrets.miniflux.file = depot.users.tazjin.secrets."miniflux.age"; + + services.miniflux = { + enable = true; + adminCredentialsFile = "/run/agenix/miniflux"; + config.LISTEN_ADDR = "127.0.0.1:6359"; + config.BASE_URL = "https://feeds.tazj.in"; + }; + + services.nginx.virtualHosts."feeds" = { + serverName = "feeds.tazj.in"; + enableACME = true; + forceSSL = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:6359"; + }; + }; +} diff --git a/users/tazjin/nixos/modules/physical.nix b/users/tazjin/nixos/modules/physical.nix index 1f8b694381..d469da7e5a 100644 --- a/users/tazjin/nixos/modules/physical.nix +++ b/users/tazjin/nixos/modules/physical.nix @@ -1,95 +1,106 @@ # Default configuration settings for physical machines that I use. -{ lib, pkgs, depot, ... }: +{ lib, pkgs, config, depot, ... }: let pass-otp = pkgs.pass.withExtensions (e: [ e.pass-otp ]); in { - # Install all the default software. - environment.systemPackages = - # programs from the depot - (with depot; [ - users.tazjin.screenLock - users.tazjin.emacs - third_party.agenix.cli - third_party.josh - ]) ++ + options = with lib; { + tazjin.emacs = mkOption { + type = types.package; + default = depot.users.tazjin.emacs; + description = '' + Derivation with my Emacs package, with configuration included. + ''; + }; + }; - # programs from nixpkgs - (with pkgs; [ - amber - bat - curl - ddcutil - direnv - dnsutils - electrum - emacsNativeComp # emacsclient - exa - fd - file - firefox - gdb - gh - git - gnupg - google-chrome - gtk3 # for gtk-launch - htop - hyperfine - iftop - imagemagick - jq - lieer - man-pages - moreutils - mosh - msmtp - mullvad-vpn - networkmanagerapplet - nix-prefetch-github - nmap - notmuch - openssh - openssl - pass-otp - pavucontrol - pinentry - pinentry-emacs - pulseaudio # for pactl - pwgen - quasselClient - rink - ripgrep - rust-analyzer - rustup - screen - scrot - thunderbird - tig - tokei - tree - unzip - vlc - volumeicon - whois - xclip - xsecurelock - zoxide - ]); + config = { + # Install all the default software. + environment.systemPackages = + # programs from the depot + (with depot; [ + users.tazjin.screenLock + users.tazjin.chase-geese + config.tazjin.emacs + third_party.agenix.cli + tools.when + ]) ++ - # Run services & configure programs for all machines. - services = { - mullvad-vpn.enable = true; - fwupd.enable = true; - }; + # programs from nixpkgs + (with pkgs; [ + (aspellWithDicts (d: [ d.ru ])) + amber + bat + curl + ddcutil + direnv + dnsutils + electrum + firefox + config.tazjin.emacs.emacs # emacsclient + expect + fd + file + gdb + git + gnupg + gtk3 # for gtk-launch + htop + hyperfine + iftop + imagemagick + josh + jq + lieer + maim + man-pages + moreutils + mosh + msmtp + networkmanagerapplet + nix-prefetch-github + nmap + notmuch + openssh + openssl + pass-otp + pavucontrol + pinentry + pinentry-emacs + pulseaudio # for pactl + pwgen + quasselClient + rink + ripgrep + rustup + screen + tig + tokei + tree + unzip + vlc + volumeicon + whois + xclip + xsecurelock + zoxide + ]); + + # Run services & configure programs for all machines. + services.fwupd.enable = true; + + # Disable the broken NetworkManager-wait-online.service + systemd.services.NetworkManager-wait-online.enable = lib.mkForce false; - # Disable the broken NetworkManager-wait-online.service - systemd.services.NetworkManager-wait-online.enable = lib.mkForce false; + # Disable the thing that prints annoying warnings when trying to + # run manually patchelfed binaries + environment.stub-ld.enable = false; - programs = { - fish.enable = true; - mosh.enable = true; - ssh.startAgent = true; + programs = { + fish.enable = true; + mosh.enable = true; + ssh.startAgent = true; + }; }; } diff --git a/users/tazjin/nixos/modules/predlozhnik.nix b/users/tazjin/nixos/modules/predlozhnik.nix index df402ce299..db20963df1 100644 --- a/users/tazjin/nixos/modules/predlozhnik.nix +++ b/users/tazjin/nixos/modules/predlozhnik.nix @@ -3,7 +3,7 @@ { services.nginx.virtualHosts."predlozhnik.ru" = { - root = depot.users.tazjin.predlozhnik; + root = depot.corp.russian.predlozhnik; enableACME = true; forceSSL = true; }; diff --git a/users/tazjin/nixos/modules/tgsa.nix b/users/tazjin/nixos/modules/tgsa.nix index ac6d940c2a..e162e0d822 100644 --- a/users/tazjin/nixos/modules/tgsa.nix +++ b/users/tazjin/nixos/modules/tgsa.nix @@ -8,8 +8,13 @@ serviceConfig = { DynamicUser = true; Restart = "always"; - ExecStart = "${depot.users.tazjin.tgsa}/bin/tgsa"; + LoadCredential = "tgsa-yandex.json:/run/agenix/tgsa-yandex"; }; + + script = '' + export YANDEX_KEY_FILE="''${CREDENTIALS_DIRECTORY}/tgsa-yandex.json" + ${depot.users.tazjin.tgsa}/bin/tgsa + ''; }; services.nginx.virtualHosts."tgsa" = { diff --git a/users/tazjin/nixos/modules/zerotier.nix b/users/tazjin/nixos/modules/zerotier.nix deleted file mode 100644 index bd503cf8f0..0000000000 --- a/users/tazjin/nixos/modules/zerotier.nix +++ /dev/null @@ -1,14 +0,0 @@ -# Configuration for my Zerotier network. - -{ - environment.persistence."/persist".directories = [ - "/var/lib/zerotier-one" - ]; - - services.zerotierone.enable = true; - services.zerotierone.joinNetworks = [ - "35c192ce9bd4c8c7" - ]; - - networking.firewall.trustedInterfaces = [ "zt7nnembs4" ]; -} diff --git a/users/tazjin/nixos/polyanka/default.nix b/users/tazjin/nixos/polyanka/default.nix deleted file mode 100644 index 95d1214ab3..0000000000 --- a/users/tazjin/nixos/polyanka/default.nix +++ /dev/null @@ -1,123 +0,0 @@ -# VPS hosted at GleSYS, running my Quassel and some random network -# stuff. - -_: # ignore readTree options - -{ config, depot, lib, pkgs, ... }: - -let - mod = name: depot.path.origSrc + ("/ops/modules/" + name); - usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); -in -{ - imports = [ - (mod "quassel.nix") - (mod "www/base.nix") - (usermod "tgsa.nix") - (usermod "predlozhnik.nix") - ]; - - # Use the GRUB 2 boot loader. - boot.loader.grub.enable = true; - boot.loader.grub.version = 2; - boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only - boot.initrd.availableKernelModules = [ "ata_piix" "vmw_pvscsi" "sd_mod" "sr_mod" ]; - - # Adjust to disk size increases - boot.growPartition = true; - - virtualisation.vmware.guest.enable = true; - virtualisation.vmware.guest.headless = true; - - nix.settings.trusted-users = [ "tazjin" ]; - - fileSystems."/" = - { - device = "/dev/disk/by-uuid/4c51357a-1e34-4b59-b169-63af1fcdce71"; - fsType = "ext4"; - }; - - networking = { - hostName = "polyanka"; - domain = "tazj.in"; - useDHCP = false; - - # Required for VPN usage - networkmanager.enable = true; - - interfaces.ens192 = { - ipv4.addresses = lib.singleton { - address = "159.253.30.129"; - prefixLength = 24; - }; - - ipv6.addresses = lib.singleton { - address = "2a02:750:7:3305::308"; - prefixLength = 64; - }; - }; - - defaultGateway = "159.253.30.1"; - defaultGateway6.address = "2a02:750:7:3305::1"; - - firewall.enable = true; - firewall.allowedTCPPorts = [ 22 80 443 ]; - - nameservers = [ - "79.99.4.100" - "79.99.4.101" - "2a02:751:aaaa::1" - "2a02:751:aaaa::2" - ]; - }; - - time.timeZone = "UTC"; - - security.acme.acceptTerms = true; - security.acme.certs."polyanka.tazj.in" = { - listenHTTP = ":80"; - email = "mail@tazj.in"; - group = "quassel"; - }; - - users.users.tazjin = { - isNormalUser = true; - extraGroups = [ "wheel" ]; - shell = pkgs.fish; - openssh.authorizedKeys.keys = depot.users.tazjin.keys.all; - }; - - security.sudo.wheelNeedsPassword = false; - - services.depot.quassel = { - enable = true; - acmeHost = "polyanka.tazj.in"; - bindAddresses = [ - "0.0.0.0" - ]; - }; - - # List packages installed in system profile. To search, run: - # $ nix search wget - environment.systemPackages = with pkgs; [ - curl - htop - jq - nmap - bat - emacs-nox - nano - wget - ]; - - programs.mtr.enable = true; - programs.mosh.enable = true; - services.openssh.enable = true; - - services.zerotierone.enable = true; - services.zerotierone.joinNetworks = [ - "35c192ce9bd4c8c7" - ]; - - system.stateVersion = "20.09"; -} diff --git a/users/tazjin/nixos/tverskoy/default.nix b/users/tazjin/nixos/tverskoy/default.nix index d42d489776..733929219a 100644 --- a/users/tazjin/nixos/tverskoy/default.nix +++ b/users/tazjin/nixos/tverskoy/default.nix @@ -15,13 +15,13 @@ in lib.fix (self: { imports = [ (mod "open_eid.nix") + (usermod "chromium.nix") (usermod "desktop.nix") (usermod "fonts.nix") (usermod "home-config.nix") (usermod "laptop.nix") (usermod "persistence.nix") (usermod "physical.nix") - (usermod "zerotier.nix") (pkgs.home-manager.src + "/nixos") ] ++ lib.optional (builtins.pathExists ./local-config.nix) ./local-config.nix; @@ -44,11 +44,10 @@ lib.fix (self: { kernelPackages = pkgs.zfsUnstable.latestCompatibleLinuxPackages; loader.systemd-boot.enable = true; loader.efi.canTouchEfiVariables = true; - zfs.enableUnstable = true; }; - virtualisation.virtualbox.host.enable = true; - users.users.tazjin.extraGroups = [ "vboxusers" ]; + virtualisation.docker.enable = true; + users.users.tazjin.extraGroups = [ "docker" "vboxusers" "adbusers" ]; fileSystems = { "/" = { @@ -96,6 +95,8 @@ lib.fix (self: { opengl = { enable = true; + driSupport32Bit = true; + extraPackages = with pkgs; [ vaapiVdpau libvdpau-va-gl @@ -120,6 +121,7 @@ lib.fix (self: { security.rtkit.enable = true; services = { + tailscale.enable = true; printing.enable = true; # expose i2c device as /dev/i2c-amdgpu-dm and make it user-accessible @@ -159,7 +161,15 @@ lib.fix (self: { }; }; - services.tailscale.enable = true; + # android stuff for hacking on Awful.apk + programs.adb.enable = true; + + # systemd-oomd seems to have been enabled by default around ~ + # December 2022, and it's really into killing my X session as soon + # as I do anything stressful to the machine + systemd.services.systemd-oomd.enable = lib.mkForce false; + + environment.systemPackages = [ pkgs.vulkan-tools ]; system.stateVersion = "20.09"; }) diff --git a/users/tazjin/nixos/zamalek/default.nix b/users/tazjin/nixos/zamalek/default.nix index dfe07107bc..a340e8a3e8 100644 --- a/users/tazjin/nixos/zamalek/default.nix +++ b/users/tazjin/nixos/zamalek/default.nix @@ -13,6 +13,7 @@ let in { imports = [ + (usermod "chromium.nix") (usermod "desktop.nix") (usermod "fonts.nix") (usermod "hidpi.nix") @@ -80,6 +81,7 @@ in services.xserver.libinput.touchpad.clickMethod = "clickfinger"; services.xserver.libinput.touchpad.tapping = false; services.avahi.enable = true; + services.tailscale.enable = true; powerManagement.powertop.enable = true; system.stateVersion = "21.11"; diff --git a/users/tazjin/predlozhnik/.gitignore b/users/tazjin/predlozhnik/.gitignore deleted file mode 100644 index 58eaf3e326..0000000000 --- a/users/tazjin/predlozhnik/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target/ -**/*.rs.bk -dist/ diff --git a/users/tazjin/predlozhnik/Cargo.lock b/users/tazjin/predlozhnik/Cargo.lock deleted file mode 100644 index 131aa134fe..0000000000 --- a/users/tazjin/predlozhnik/Cargo.lock +++ /dev/null @@ -1,460 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "boolinator" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" - -[[package]] -name = "bumpalo" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "gloo" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23947965eee55e3e97a5cd142dd4c10631cc349b48cecca0ed230fd296f568cd" -dependencies = [ - "gloo-console", - "gloo-dialogs", - "gloo-events", - "gloo-file", - "gloo-render", - "gloo-storage", - "gloo-timers", - "gloo-utils", -] - -[[package]] -name = "gloo-console" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" -dependencies = [ - "gloo-utils", - "js-sys", - "serde", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-dialogs" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-events" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-file" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" -dependencies = [ - "gloo-events", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-render" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-storage" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" -dependencies = [ - "gloo-utils", - "js-sys", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40913a05c8297adca04392f707b1e73b12ba7b8eab7244a4961580b1fd34063c" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "itoa" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" - -[[package]] -name = "js-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "once_cell" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" - -[[package]] -name = "predlozhnik" -version = "0.1.0" -dependencies = [ - "lazy_static", - "maplit", - "wasm-bindgen", - "yew", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "scoped-tls-hkt" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e9d7eaddb227e8fbaaa71136ae0e1e913ca159b86c7da82f3e8f0044ad3a63" - -[[package]] -name = "serde" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "syn" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "unicode-ident" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasm-bindgen" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" - -[[package]] -name = "web-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "yew" -version = "0.19.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1ccb53e57d3f7d847338cf5758befa811cabe207df07f543c06f502f9998cd" -dependencies = [ - "console_error_panic_hook", - "gloo", - "gloo-utils", - "indexmap", - "js-sys", - "scoped-tls-hkt", - "slab", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "yew-macro", -] - -[[package]] -name = "yew-macro" -version = "0.19.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fab79082b556d768d6e21811869c761893f0450e1d550a67892b9bce303b7bb" -dependencies = [ - "boolinator", - "lazy_static", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] diff --git a/users/tazjin/predlozhnik/Cargo.toml b/users/tazjin/predlozhnik/Cargo.toml deleted file mode 100644 index 90205bc4fb..0000000000 --- a/users/tazjin/predlozhnik/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "predlozhnik" -version = "0.1.0" -edition = "2021" - -[dependencies] -maplit = "1.0" -lazy_static = "1.4" -yew = "0.19" - -# needs to be in sync with nixpkgs -wasm-bindgen = "= 0.2.83" diff --git a/users/tazjin/predlozhnik/default.nix b/users/tazjin/predlozhnik/default.nix deleted file mode 100644 index 2137be1112..0000000000 --- a/users/tazjin/predlozhnik/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ lib, pkgs, ... }: - -let - wasmRust = pkgs.rust-bin.stable.latest.default.override { - targets = [ "wasm32-unknown-unknown" ]; - }; - - cargoToml = with builtins; fromTOML (readFile ./Cargo.toml); - - wasmBindgenMatch = - cargoToml.dependencies.wasm-bindgen == "= ${pkgs.wasm-bindgen-cli.version}"; - - assertWasmBindgen = assert (lib.assertMsg wasmBindgenMatch '' - Due to instability in the Rust WASM ecosystem, the trunk build - tool enforces that the Cargo-dependency version of `wasm-bindgen` - MUST match the version of the CLI supplied in the environment. - - This can get out of sync when nixpkgs is updated. To resolve it, - wasm-bindgen must be bumped in the Cargo.toml file and cargo needs - to be run to resolve the dependencies. - - Versions of `wasm-bindgen` in Cargo.toml: - - Expected: '= ${pkgs.wasm-bindgen-cli.version}' - Actual: '${cargoToml.dependencies.wasm-bindgen}' - ''); pkgs.wasm-bindgen-cli; - - deps = with pkgs; [ - binaryen - sass - wasmRust - trunk - assertWasmBindgen - ]; - -in -pkgs.rustPlatform.buildRustPackage rec { - pname = "predlozhnik"; - version = "canon"; - src = lib.cleanSource ./.; - cargoLock.lockFile = ./Cargo.lock; - - buildPhase = '' - export PATH=${lib.makeBinPath deps}:$PATH - mkdir home - export HOME=$PWD/.home - env - trunk build --release -d $out - ''; - - dontInstall = true; -} diff --git a/users/tazjin/predlozhnik/index.css b/users/tazjin/predlozhnik/index.css deleted file mode 100644 index 3529574c4f..0000000000 --- a/users/tazjin/predlozhnik/index.css +++ /dev/null @@ -1,29 +0,0 @@ -body { - max-width: 800px; - margin: 40px auto; -} - -#header { - display: flex; - flex-direction: column; -} - -.btn.btn-ghost:disabled { - border-color: #9f9f9f; - color: #9f9f9f; -} - -#predlogi,#padezhi { - display: flex; - flex-direction: row; - flex-wrap: wrap; -} - -.btn { - margin: 3px; - flex-grow: 1; -} - -.footer { - text-align: right; -} diff --git a/users/tazjin/predlozhnik/index.html b/users/tazjin/predlozhnik/index.html deleted file mode 100644 index 6af1adc0bf..0000000000 --- a/users/tazjin/predlozhnik/index.html +++ /dev/null @@ -1,24 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" - href="https://unpkg.com/terminal.css@0.7.2/dist/terminal.min.css" /> - <link data-trunk rel="inline" href="index.css"> - <title>Предложник</title> - - <!-- Yandex.RTB --> - <script>window.yaContextCb=window.yaContextCb||[]</script> - <script src="https://yandex.ru/ads/system/context.js" async></script> - </head> - <body> - <noscript> - <h1>Предложник</h1> - <p> - ... показывает с какими падежами употребляются предлоги в - русском языке. Но, к сожалению, только с помощью Javascript. - </p> - </noscript> - </body> -</html> diff --git a/users/tazjin/predlozhnik/src/main.rs b/users/tazjin/predlozhnik/src/main.rs deleted file mode 100644 index 6c0311a66c..0000000000 --- a/users/tazjin/predlozhnik/src/main.rs +++ /dev/null @@ -1,345 +0,0 @@ -use yew::html::Scope; -use yew::prelude::*; - -use lazy_static::lazy_static; -use maplit::hashmap; -use std::collections::BTreeSet; -use std::collections::HashMap; - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -enum Падеж { - Именительный, - Родительный, - Дательный, - Винительный, - Творительный, - Предложный, -} - -impl Падеж { - const ВСЕ: [Self; 6] = [ - Self::Именительный, - Self::Родительный, - Self::Дательный, - Self::Винительный, - Self::Творительный, - Self::Предложный, - ]; - - fn вопрос(&self) -> &str { - use Падеж::*; - match self { - Именительный => "кто? Что?", - Родительный => "кого? Чего?", - Дательный => "кому? Чему?", - Винительный => "кого? Что?", - Творительный => "кем? Чем?", - Предложный => "ком? Чём?", - } - } -} - -lazy_static! { - static ref ПО_ПРЕДЛОГУ: HashMap<&'static str, BTreeSet<Падеж>> = { - use Падеж::*; - - hashmap! { - "без" => BTreeSet::from([Родительный]), - "близ" => BTreeSet::from([Родительный]), - "в" => BTreeSet::from([Винительный, Предложный]), - "вместо" => BTreeSet::from([Родительный]), - "вне" => BTreeSet::from([Родительный]), - "возле" => BTreeSet::from([Родительный]), - "вокруг" => BTreeSet::from([Родительный]), - "вроде" => BTreeSet::from([Родительный]), - "для" => BTreeSet::from([Родительный]), - "до" => BTreeSet::from([Родительный]), - "за" => BTreeSet::from([Винительный, Творительный]), - "из" => BTreeSet::from([Родительный]), - "из-за" => BTreeSet::from([Родительный]), - "из-под" => BTreeSet::from([Родительный]), - "к" => BTreeSet::from([Дательный]), - "кроме" => BTreeSet::from([Родительный]), - "между" => BTreeSet::from([Творительный, Родительный]), - "на" => BTreeSet::from([Винительный, Предложный]), - "над" => BTreeSet::from([Творительный]), - "нет" => BTreeSet::from([Родительный]), - "о" => BTreeSet::from([Винительный, Предложный]), - "около" => BTreeSet::from([Родительный]), - "от" => BTreeSet::from([Родительный]), - "перед" => BTreeSet::from([Творительный]), - "по" => BTreeSet::from([Винительный, Дательный, Предложный]), - "под" => BTreeSet::from([Винительный, Творительный]), - "после" => BTreeSet::from([Родительный]), - "при" => BTreeSet::from([Предложный]), - "про" => BTreeSet::from([Винительный]), - "ради" => BTreeSet::from([Родительный]), - "с" => BTreeSet::from([Родительный, Винительный, Творительный]), - "сквозь" => BTreeSet::from([Винительный]), - "среди" => BTreeSet::from([Родительный]), - "у" => BTreeSet::from([Родительный]), - "через" => BTreeSet::from([Винительный]), - } - }; - static ref ПО_ПАДЕЖУ: HashMap<Падеж, BTreeSet<&'static str>> = { - let mut m = hashmap!(); - - for c in Падеж::ВСЕ { - let mut предлоги: BTreeSet<&'static str> = BTreeSet::new(); - for (k, v) in &*ПО_ПРЕДЛОГУ { - if v.contains(&c) { - предлоги.insert(k); - } - } - - m.insert(c, предлоги); - } - - m - }; - static ref ПАДЕЖИ: BTreeSet<Падеж> = BTreeSet::from(Падеж::ВСЕ); - static ref ПРЕДЛОГИ: BTreeSet<&'static str> = { - let mut s: BTreeSet<&'static str> = BTreeSet::new(); - - for п in ПО_ПРЕДЛОГУ.keys() { - s.insert(п); - } - - s - }; -} - -fn исключение(предлог: &str, падеж: Падеж) -> Option<Html> { - use Падеж::*; - - match (предлог, падеж) { - ("в", Винительный) => Some(html! {"Во что? В кого?"}), - - ("о", Винительный) => Some(html! { - <> - <p>{"О кого? Обо что?"}</p> - <p>{"Редко используется. Например:"}</p> - <ul> - <li>{"Удариться о притолоку."}</li> - <li>{"точить о камень."}</li> - </ul> - </> - }), - - ("между", Родительный) => Some(html! { - <> - <p>{"Между чего? Между кого?"}</p> - <p>{"Редко используется. Например:"}</p> - <ul> - <li>{"Читаю между строк."}</li> - <li>{"Между людей установился мир."}</li> - </ul> - </> - }), - - _ => None, - } -} - -enum Сообщение { - ВыбралПадеж(Option<Падеж>), - ВыбралПредлог(Option<&'static str>), -} - -#[derive(Default)] -struct Модель { - падеж: Option<Падеж>, - предлог: Option<&'static str>, -} - -struct Вывод { - доступные_падежи: BTreeSet<Падеж>, - доступные_предлоги: BTreeSet<&'static str>, - объяснение: Option<Html>, -} - -fn объясни(падеж: Падеж, предлог: &str) -> Html { - let иск = match исключение(предлог, падеж) { - Some(exp) => html! { exp }, - None => html! { format!("{} {}", предлог, падеж.вопрос()) }, - }; - - html! { - <div id="obyasnenie"> - <hr/> - <h2>{"Пример:"}</h2> - {иск} - </div> - } -} - -fn ограничить(м: &Модель) -> Вывод { - match (м.падеж, &м.предлог) { - (Some(пж), Some(пл)) => Вывод { - доступные_падежи: (*ПО_ПРЕДЛОГУ)[пл].clone(), - доступные_предлоги: (*ПО_ПАДЕЖУ)[&пж].clone(), - объяснение: Some(объясни(пж, пл)), - }, - - (Some(пж), None) => Вывод { - доступные_падежи: BTreeSet::from([пж]), - доступные_предлоги: (*ПО_ПАДЕЖУ)[&пж].clone(), - объяснение: None, - }, - - (None, Some(пл)) => Вывод { - доступные_падежи: (*ПО_ПРЕДЛОГУ)[пл].clone(), - доступные_предлоги: BTreeSet::from([*пл]), - объяснение: None, - }, - - (None, None) => Вывод { - доступные_падежи: ПАДЕЖИ.clone(), - доступные_предлоги: ПРЕДЛОГИ.clone(), - объяснение: None, - }, - } -} - -fn класс_кнопки(выбран: bool, доступен: bool) -> String { - let класс = "btn ".to_string(); - класс - + match (выбран, доступен) { - (true, _) => "btn-primary", - (false, true) => "btn-ghost btn-primary", - (false, false) => "btn-ghost btn-default", - } -} - -fn покажи_предлог( - link: &Scope<Модель>, - м: &Модель, - вв: &Вывод, - п: &'static str, -) -> Html { - let выбран = м.предлог == Some(п); - let доступен = вв.доступные_предлоги.contains(п); - let класс = класс_кнопки(выбран, доступен); - - html! { - <button class={класс} - onclick={link.callback(move |_| if выбран { - Сообщение::ВыбралПредлог(None) - } else { - Сообщение::ВыбралПредлог(Some(п)) - })} - disabled={!доступен}> - {п} - </button> - } -} - -fn покажи_падеж( - link: &Scope<Модель>, м: &Модель, вв: &Вывод, п: Падеж -) -> Html { - let выбран = м.падеж == Some(п); - let доступен = вв.доступные_падежи.contains(&п); - let класс = класс_кнопки(выбран, доступен); - - html! { - <button class={класс} - onclick={link.callback(move |_| if выбран { - Сообщение::ВыбралПадеж(None) - } else { - Сообщение::ВыбралПадеж(Some(п)) - })} - disabled={!доступен}> - {format!("{:?}", п)} - </button> - } -} - -impl Component for Модель { - type Message = Сообщение; - type Properties = (); - - fn create(_ctx: &Context<Self>) -> Self { - Default::default() - } - - fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool { - match msg { - Сообщение::ВыбралПадеж(пж) => self.падеж = пж, - Сообщение::ВыбралПредлог(пл) => self.предлог = пл, - } - - true - } - - fn view(&self, ctx: &Context<Self>) -> Html { - let вв = ограничить(self); - let link = ctx.link(); - - let кнопки_предлогов = ПРЕДЛОГИ - .iter() - .map(|п| покажи_предлог(link, self, &вв, п)) - .collect::<Html>(); - - let кнопки_падежов = ПАДЕЖИ - .iter() - .map(|п| покажи_падеж(link, self, &вв, *п)) - .collect::<Html>(); - - let объяснение = вв.объяснение.map(|exp| exp).unwrap_or_else(|| html! {}); - - let footer = html! { - <footer> - <hr/> - <p class="footer"> - <a href="https://code.tvl.fyi/tree/users/tazjin/predlozhnik">{"код"}</a> - {" | "} - {"сделано "}<a href="https://tvl.su">{"ООО \"ТВЛ\""}</a> - </p> - </footer> - }; - - let код_рекламы = r#" -window.yaContextCb.push(()=>{ - Ya.Context.AdvManager.render({ - renderTo: 'yandex_rtb_R-A-1773485-1', - blockId: 'R-A-1773485-1' - }) -}) -"#; - - let реклама = html! { - <div id="ad"> - <div id="yandex_rtb_R-A-1773485-1"></div> - <script>{код_рекламы}</script> - </div> - }; - - html! { - <> - <div id="header"> - <h1>{"Предложник"}</h1> - <p>{"... показывает с какими падежами употребляются предлоги в русском языке."}</p> - </div> - - <h2>{"Выбирай предлог:"}</h2> - <div id="predlogi"> - {кнопки_предлогов} - </div> - <hr/> - - <h2>{"Выбирай падеж:"}</h2> - <div id="padezhi"> - {кнопки_падежов} - </div> - - {объяснение} - {footer} - {реклама} - </> - } - } -} - -fn main() { - yew::start_app::<Модель>(); -} diff --git a/users/tazjin/presentations/tvix-eval-2023/README.md b/users/tazjin/presentations/tvix-eval-2023/README.md new file mode 100644 index 0000000000..b14ba8ff50 --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/README.md @@ -0,0 +1,12 @@ +These are the slides for a talk at the Moscow Rust User Group / +ProgMSK on 2023-09-07. + +After building, the presentation can be launched with `pdfpc` +(available in `nixpkgs`), like this: + +``` +pdfpc --windowed=both result/presentation.pdf -R presentation.pdfpc -d 40 +``` + +I keep the JSON file formatted using `jq . presentation.pdfpc | sponge +presentation.pdfpc` for easier diffs. diff --git a/users/tazjin/presentations/tvix-eval-2023/cppnix-example-lexer.cpp b/users/tazjin/presentations/tvix-eval-2023/cppnix-example-lexer.cpp new file mode 100644 index 0000000000..7c52bce8b6 --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/cppnix-example-lexer.cpp @@ -0,0 +1,13 @@ +attrpath + : attrpath '.' attr { + $$ = $1; $1->push_back(AttrName(data->symbols.create($3))); + } + | attrpath '.' string_attr + { $$ = $1; + ExprString * str = dynamic_cast<ExprString *>($3); + if (str) { + $$->push_back(AttrName(data->symbols.create(str->s))); + delete str; + } else + $$->push_back(AttrName($3)); + } diff --git a/users/tazjin/presentations/tvix-eval-2023/cppnix-example-smuggling.cpp b/users/tazjin/presentations/tvix-eval-2023/cppnix-example-smuggling.cpp new file mode 100644 index 0000000000..37b9219b2e --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/cppnix-example-smuggling.cpp @@ -0,0 +1,12 @@ +struct Env { + // ... some struct fields ... + Value* values[0]; +}; + +// .... + +if (env->type == Env::HasWithExpr) { + // ... + evalAttrs(*env->up, (Expr *) env->values[0], *v, noPos, "<borked>"); + // ^^^^^^^^^^^^^^^^^^^^^^^ +} diff --git a/users/tazjin/presentations/tvix-eval-2023/default.nix b/users/tazjin/presentations/tvix-eval-2023/default.nix new file mode 100644 index 0000000000..a4d855197c --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/default.nix @@ -0,0 +1,63 @@ +{ depot, pkgs, ... }: + +let + inherit (pkgs) fontconfig texlive stdenv imagemagick runCommand qrencode; + + tex = texlive.combine { + inherit (texlive) + babel + babel-russian + beamer + beamertheme-metropolis + etoolbox + euenc + extsizes + fontspec + listings + xetex + minted + ms + pgfopts + scheme-basic + translator; + }; + + linksQrCode = runCommand "qrcode.png" { } '' + ${qrencode}/bin/qrencode -o code.png -s 8 \ + --background=fafafa \ + --foreground=000000 \ + 'https://tazj.in/blog/tvix-eval-talk-2023' + + # latex has trouble with the PDF produced by qrencode + ${imagemagick}/bin/convert code.png $out + ''; +in +stdenv.mkDerivation { + name = "progmsk-tvix-eval"; + src = ./.; + + nativeBuildInputs = [ tex imagemagick fontconfig ]; + + FONTCONFIG_FILE = pkgs.makeFontsConf { + fontDirectories = with pkgs; [ jetbrains-mono fira fira-code fira-mono ]; + }; + + buildPhase = '' + # LaTeX needs a cache folder in /home/ ... + mkdir home + export HOME=$PWD/home + + cp ${depot.tvix.logo}/logo.png tvix-logo.png + cp ${linksQrCode} qrcode.png + + # As usual, TeX needs to be run twice ... + ${tex}/bin/xelatex presentation.tex + ${tex}/bin/xelatex presentation.tex + ''; + + installPhase = '' + mkdir -p $out + cp presentation.pdf $out/ + cp $src/presentation.pdfpc $out/ + ''; +} diff --git a/users/tazjin/presentations/tvix-eval-2023/presentation.pdfpc b/users/tazjin/presentations/tvix-eval-2023/presentation.pdfpc new file mode 100644 index 0000000000..ab5cba68bf --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/presentation.pdfpc @@ -0,0 +1,98 @@ +{ + "pdfpcFormat": 2, + "duration": 40, + "disableMarkdown": false, + "noteFontSize": 20, + "pages": [ + { + "idx": 1, + "label": "2", + "overlay": 0, + "note": "Привет, меня зовут .... Я уже много лет, с 2016г. примерно, пишу на Расте, и хотя на работе у меня часто бывают другие языки, Раст - любимый мой язык.\n\nПару лет назад, во время Кодида, я создал онлайн-коммюнити ТВЛ, и сегодня хочу вам об одном из наших проектов рассказать." + }, + { + "idx": 2, + "label": "3", + "overlay": 0, + "note": "монорепо: объяснить. Весь код орга в одном месте. Единный тулинг. Много из нас раньше работали в компаниях, где так делают (нп Гугл).\n\nМы хотели создать такой же тулинг, но открыто. Но у нас меньше ресурсов чем у Гугла, намного меньше. Пришлось выбрать эфф. способ.\nФокусируем на Никс, потому что (...). Есть доклад.\n\nМы начали его не только для пакетов использовать (конфиг и тд.), хотелось решение, которое работает везде." + }, + { + "idx": 3, + "label": "4", + "overlay": 0, + "note": "Будем фокусировать только на язык сейчас. Остальные части интересные, но не сегодня.\nЯзык ленивый, значит только вычисляем код, когда его результат нужен где-то.\nЗначит, нам нужен рантайм-представление отложенных вычислений.\nОрганично развивался: добавили фичи, когда нуждались. Много функтции работают только случайно, комбинации фич - часто странно. (шутка про С++?)\nНо есть хороший фактор: весь публичный код в принципе в одном репо. Объяснять nixpkgs." + }, + { + "idx": 4, + "label": "5", + "overlay": 0, + "note": "Текушая имплементация на С++. Вот пример. Кто-то здесь понимает, что мы видем? Это часть парсера в як, но тут создают рантайм-значения во время парсинга. Очень сложно понимать, читать, дебажить и так далее.\nЧитали парсер, и даже нашли там неизвестные фичи языка." + }, + { + "idx": 5, + "label": "6", + "overlay": 0, + "note": "Второй пример. Есть стракт Env, которая используется во многих местах в коде. Там массив типа Value.\nВот использование этого массива. Что мы видем? Кто понимает?\nДа, там на самом деле происходит каст на другой тип. Значит, в структуре добавляют данные, которые не подойдет. Очень unsafe!\n\nДа, что же делать? Пытались почистить код, но случилось burnout очень быстро. Меняешь одну маленькую штуку -> segfaults.\nПочему код вот такой? -> объяснять.\nПришлась очевидная идея." + }, + { + "idx": 6, + "label": "6", + "overlay": 1, + "note": "Переписать проекты полностью, обычно очень сложно. Но мы можем менять арх., и обходить переписивание некоторых частей.\nРаст - нам очевидный выбор для имплементация языка. Много нас знают Раст, и в целом, почему именно Раст, вы уже сами понимаете.\n\nМы от NLNet, организация, ..., получили денги за этого и начали с языком. Этот проект называем tvix-eval.\n\nЕсть еще одна важная причина для выбора Раста." + }, + { + "idx": 7, + "label": "6", + "overlay": 2, + "note": "Пару лет назад, шведский парень юзернеймом, который нельзя происносить, написал на Расте очень быстрый и в целом хороший парсер для Никса.\nЭтот парсер уже используется в разных с Никсом связанных проектах. Он скорее всего в пути стать дефольтним парсером Никса.\nКонечно, неплохо если мы его тоже используем.\nК сожалению, автор рникса умерл в 2021 году. Мали исвестно о том, что случилось. Мы ему очень благодарные, и я просто хотел его здесь упомянуть." + }, + { + "idx": 9, + "label": "8", + "overlay": 0, + "note": "показать opcode.rs, compiler/mod (compile_binop)\n\nчтобы он не разжирел (про variant_size_differences)\n" + }, + { + "idx": 10, + "label": "9", + "overlay": 0, + "note": "показать value/mod.rs, потом value/list.rs\n\nкороткая объяснение ситуации с Gc<...> vs. Rc<...>" + }, + { + "idx": 11, + "label": "10", + "overlay": 0, + "note": "показать vm/mod.rs\n\nпоследовательно выпольняет инструктции в execute_bytecode\n\nсначала на алфавитным порядке, потом с помощью профайлера меняли это" + }, + { + "idx": 12, + "label": "10", + "overlay": 1, + "note": "показать диаграмму\n\nгенераторый можно приостановить\n\nTCO - хвостовый вызов\n\nasync - очень наязчивный (intrusive), надо было его везде добавить, неудоб" + }, + { + "idx": 13, + "label": "10", + "overlay": 2, + "note": "Зависимо от времени, можно либо только про tvixbolt, либо тоже про тесты из cppnix" + }, + { + "idx": 14, + "label": "11", + "overlay": 0, + "note": "на самом деле удивительно легко, но сталкивались с проблемой, что он иногда перестал работать\n\nпоказать пример с SystemTime::now\n\nесть кое-какие библиотеки, которые мб помогут, но мы их пока не проверили\n\nв целом, wasm на расте довольно удобно" + }, + { + "idx": 15, + "label": "12", + "overlay": 0, + "note": "открытый проект, принимаем коммиты от всех\n\nесть еще баги, TODOs, и тд в tvix-eval\n\nно есть тоже остальные части твикса, что-то найдется" + }, + { + "idx": 16, + "label": "13", + "overlay": 0, + "note": "спасибо всем, вот ссылки, на QR-коде есть все вот этот вот, и там тоже потом добавлю сам доклад\n\nеще завтра начинается NixCon, если вам вдруг интересно, можно онлайн посмотреть. Там будет доклад про tvix тоже, но об остальных частях." + } + ] +} diff --git a/users/tazjin/presentations/tvix-eval-2023/presentation.tex b/users/tazjin/presentations/tvix-eval-2023/presentation.tex new file mode 100644 index 0000000000..294dad7942 --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/presentation.tex @@ -0,0 +1,148 @@ +\documentclass[12pt]{beamer} + +\usepackage[utf8]{inputenc} +\usepackage[main=russian,english]{babel} +\usepackage{fontspec} +\usepackage{listings} + +\setmainfont{JetBrains Mono} +\setsansfont{JetBrains Mono} + +\usetheme{metropolis} +\newenvironment{code}{\ttfamily}{\par} +\title{tvix-eval \\ компилятор и рантайм для Nix, на Rust} + +\titlegraphic{\vspace{4.8cm}\flushright\includegraphics[width=6cm,keepaspectratio=true]{tvix-logo.png}} + +\date{2023-09-07} +\author{Винсент Амбо} +\institute{TVL} + +\begin{document} + %% Slide -1 (before counter): + \begin{frame} + \begin{center} + \titlepage + \end{center} + \end{frame} + + %% Slide 0 (title): + \begin{frame} + \begin{center} + \titlepage + \end{center} + \end{frame} + + %% Slide 1: + \begin{frame}{\textbf{Т}he \textbf{V}irus \textbf{L}ounge} + \begin{itemize} + \item онлайн-комьюнити, занимающееся тулингом для монорепо + \item основной фокус на Nix + \item Nix не только для сборки пакетов + \item Хотелось решение, чтобы использовать Nix везде + \end{itemize} + \end{frame} + + %% Slide 2: + \begin{frame}{Особенности языка Nix} + \begin{itemize} + \item Ленивый язык. Вычислять все сразу нельзя. + \item Язык развивался органично. + \item Большинство кода на Nix --- в одном месте: \begin{code}nixpkgs\end{code} + \end{itemize} + \end{frame} + + %% Slide 3: + \begin{frame}{Текущая имплементация: C++ Nix} + \lstinputlisting[ + language=c++, + basicstyle={\scriptsize} + ]{cppnix-example-lexer.cpp} + \end{frame} + + %% Slide 4: + \begin{frame}{Текущая имплементация: C++ Nix} + \lstinputlisting[ + language=c++, + basicstyle={\scriptsize} + ]{cppnix-example-smuggling.cpp} + \end{frame} + + %% Slide 5: + \section{``Let's rewrite it in Rust!''} + + %% Slide 6: + \section*{Спасибо, jD91mZM2!\\\normalsize{автор ``rnix-parser''; *2002 - \textdagger 2021}} + + %% Slide 7: + \begin{frame}{tvix-eval, - (язык) Nix, на Rust} + \begin{itemize} + \item написано с существующим парсером + \item bytecode-интерпретатор, вместо tree-walk + \item должна работать не только для остальных частей tvix + \end{itemize} + \end{frame} + + %% Slide 8: + \begin{frame}{tvix-eval, основные части} + \begin{enumerate} + \item собственный байткод и компилятор + \end{enumerate} + \end{frame} + + %% показать opcode.rs, быстро показать compiler/mod.rs + + %% Slide 9: + \begin{frame}{tvix-eval, основные части} + \begin{enumerate} + \item собственный байткод и компилятор + \item представление значений языка в рантайме + \end{enumerate} + \end{frame} + + %% показать Value + + %% Slide 10: + \begin{frame}{tvix-eval, основные части} + \begin{enumerate} + \item собственный байткод и компилятор + \item представление значении языка в рантайме + \item ... и сам рантайм! + \end{enumerate} + \end{frame} + + %% показать VM + + \section{``Подожди, написать рантайм же не так просто?''} + + %% объяснить проблему со стеком и решение, показать диаграмму + + \section{``А откуда знаешь, что это все правильно работает?''} + + %% показать как тесты работают + %% объяснить дебагинг, Твиксболт и тд + + %% Slide 10: + \begin{frame}{tvix-eval, в браузере} + \begin{itemize} + \item удивительно легко делать + \item но есть сложности в \begin{code}std::\end{code} + % показать пример + \end{itemize} + \end{frame} + + %% Slide 11: + \begin{frame}{А что дальше?} + В tvix-eval есть еще кое-какие интересные проблемы. Может ты их + решишь? + \end{frame} + + \begin{frame}{Спасибо!} + \begin{center} + \includegraphics[width=6cm,keepaspectratio=true]{qrcode.png} + + https://tazj.in/blog/tvix-eval-talk-2023 \\ + t.me/tazjin | t.me/tazlog + \end{center} + \end{frame} +\end{document} diff --git a/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/.gitignore b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/.gitignore new file mode 100644 index 0000000000..73b9c106db --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/.gitignore @@ -0,0 +1,2 @@ +target/ +dist/ diff --git a/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/Cargo.lock b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/Cargo.lock new file mode 100644 index 0000000000..ef879254cb --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/Cargo.lock @@ -0,0 +1,899 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "anymap2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "boolinator" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "gloo" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28999cda5ef6916ffd33fb4a7b87e1de633c47c0dc6d97905fee1cdaa142b94d" +dependencies = [ + "gloo-console", + "gloo-dialogs", + "gloo-events", + "gloo-file", + "gloo-history", + "gloo-net", + "gloo-render", + "gloo-storage", + "gloo-timers", + "gloo-utils", + "gloo-worker", +] + +[[package]] +name = "gloo-console" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" +dependencies = [ + "gloo-events", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85725d90bf0ed47063b3930ef28e863658a7905989e9929a8708aab74a1d5e7f" +dependencies = [ + "gloo-events", + "gloo-utils", + "serde", + "serde-wasm-bindgen", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-render" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-worker" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" +dependencies = [ + "anymap2", + "bincode", + "gloo-console", + "gloo-utils", + "js-sys", + "serde", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "implicit-clone" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c6ecbd987bb94f1f3c76c6787879756cf4b6f73bfff48d79308e8c56b46f65f" +dependencies = [ + "indexmap", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pinned" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b" +dependencies = [ + "futures", + "rustversion", + "thiserror", +] + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prokio" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b55e106e5791fa5a13abd13c85d6127312e8e09098059ca2bc9b03ca4cf488" +dependencies = [ + "futures", + "gloo", + "num_cpus", + "once_cell", + "pin-project", + "pinned", + "tokio", + "tokio-stream", + "wasm-bindgen-futures", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "tokio" +version = "1.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "pin-project-lite", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.29", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-fs-demo" +version = "0.1.0" +dependencies = [ + "yew", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "yew" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dbecfe44343b70cc2932c3eb445425969ae21754a8ab3a0966981c1cf7af1cc" +dependencies = [ + "console_error_panic_hook", + "futures", + "gloo", + "implicit-clone", + "indexmap", + "js-sys", + "prokio", + "rustversion", + "serde", + "slab", + "thiserror", + "tokio", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "yew-macro", +] + +[[package]] +name = "yew-macro" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b64c253c1d401f1ea868ca9988db63958cfa15a69f739101f338d6f05eea8301" +dependencies = [ + "boolinator", + "once_cell", + "prettyplease", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/Cargo.toml b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/Cargo.toml new file mode 100644 index 0000000000..4a445065e4 --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "wasm-fs-demo" +version = "0.1.0" +edition = "2021" + +[dependencies] +yew = { version = "0.20.0", features = [ "csr" ]} diff --git a/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/index.html b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/index.html new file mode 100644 index 0000000000..e024c466cd --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/index.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>wasm-fs-demo</title> + </head> +</html> diff --git a/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/src/main.rs b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/src/main.rs new file mode 100644 index 0000000000..4ad177ad7a --- /dev/null +++ b/users/tazjin/presentations/tvix-eval-2023/wasm-fs-demo/src/main.rs @@ -0,0 +1,41 @@ +use std::time::{SystemTime, UNIX_EPOCH}; +use yew::prelude::*; + +fn time_example() -> Html { + let epoch = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(duration) => duration.as_secs(), + Err(err) => { + return html! { + format!("failed to calculate duration: {}", err) + } + } + }; + + html! { + <p> + {"Seconds since epoch: "}{epoch} + </p> + } +} + +struct App; +impl Component for App { + type Message = (); + type Properties = (); + + fn create(_: &Context<Self>) -> Self { + Self + } + + fn update(&mut self, _: &Context<Self>, _: Self::Message) -> bool { + false + } + + fn view(&self, _: &Context<Self>) -> Html { + time_example() + } +} + +fn main() { + yew::Renderer::<App>::new().render(); +} diff --git a/users/tazjin/secrets/default.nix b/users/tazjin/secrets/default.nix new file mode 100644 index 0000000000..5550103c5a --- /dev/null +++ b/users/tazjin/secrets/default.nix @@ -0,0 +1,3 @@ +{ depot, ... }: + +depot.ops.secrets.mkSecrets ./. (import ./secrets.nix) diff --git a/users/tazjin/secrets/geesefs-tazjins-files.age b/users/tazjin/secrets/geesefs-tazjins-files.age new file mode 100644 index 0000000000..9132c7d108 --- /dev/null +++ b/users/tazjin/secrets/geesefs-tazjins-files.age @@ -0,0 +1,18 @@ +age-encryption.org/v1 +-> ssh-ed25519 dcsaLw SrmIul/C/aRTYy5+vVBB0H2bS65XayYf2TXrOSTEbGg +Js016EtAxiFmyJ4gTmXEjsKT9JmIntcMNgAds+qT7Js +-> ssh-ed25519 zcCuhA NfUQBKL1KgvUosB2y3oI5HwPjA+4kf8kbBbpNf43JAk +oE4R2rz1sdBitKzQlzMzneyu8Rvc5utHYRyCeGCQR8g +-> ssh-rsa zXi7VA +aDDiygAF5benqqJ1387F9qVDyvb48BkBLAwRi7eUYWkG41s9XUdmK5ppjFdxy1c8 +fx5YcPjO3m84pIv0RxiK7rZhkVi1/eiHhT5lId83wIzQdybjKFSc85YjFO3mGv9A +EeFMEmlfsRkBHYq/j6Npbg4M5kMxSuSwGSyt6qnoHSWT2phS+41WLA/XT9ln4pRR +dBDO0ZyK/CpgfDuGo/JARLiGeEMwt7SvkyXidcbD8glg9buu1VGxb/8m/ob1yrbn +y3mjfOFzO2zF8ZHuScWQlZgvaVk412Xne+n+wva12tS52dEX4FRSMtmUOB8Ai4oq +wvWB6Ikru5jXRxe8NgDoZw +-> ssh-ed25519 At5Mag yBwWJVhArq9iwngwaIph56iGfje8T55Ig0nW9268Kic +T9IWxRJF1U0STinVlBJoaGoegERnWRjnGZeW0HHGQ9Y +-> C"!?nfs%-grease >>.%|I mA Fd7?aw2m 37I +vRH3yR7+Ow +--- AKc40DwXghKw6GHzJUYNJYE0JqMr4M+hR41VRA1IvS4 +tڜ)u;T '8=S7R<Cxtz_md0ZH2^Nj*Cɗ 늣1yƼae۹8c~i 5/xş7nS^asygޒЯ(C͠%N|Y!vAI \ No newline at end of file diff --git a/users/tazjin/secrets/miniflux.age b/users/tazjin/secrets/miniflux.age new file mode 100644 index 0000000000..753dc6f034 --- /dev/null +++ b/users/tazjin/secrets/miniflux.age @@ -0,0 +1,14 @@ +age-encryption.org/v1 +-> ssh-ed25519 dcsaLw SJBK+ym6o6dcB/+HFWzArbXS9RmyDjnglVxcXduJA1g +pPWIi2A4G4X7I14HoZUWsNd/MOfhW1ZanwB/5OROSrw +-> ssh-ed25519 zcCuhA oo/8OTqpV85g/9pha0qkmxwlYAlsc7v+nXbbtj67Jmc +AexsAIgW6e5fYoPNJJZYdP61OvON2bKiL9ZJgLdG/zU +-> ssh-ed25519 ph9lig 4evTl0M3SfdlmTixm3WnVqfHMPf/TYIyBKPdlfPisC0 +AK4GyhgqXN2wxbcFRGwbNNQJ4/2iFPt3CKGHosNJbmY +-> ssh-ed25519 At5Mag JJ8r/qD5i+LLAY7jnnHXAgykAuHtzxtGGzdqw7BAogY +wotjW3yaTq1IdqVUwoCVwzglXsmnzniQIt7SDBrF4jY +-> sPHo{W-grease , h6 =mEp^w `ccnF +QQEb+Vh1+Fv++oPQwdTfOB2Cg5JaP4GCOq0o3J+xSqCY1gE0cguwLGXwa6+Tylu2 +Kuh4pMovAxnlHUt44u6f +--- yWQyncCrxJzVHffFaFT704BEp8hjUn09a+23r4S39N4 +}ң l I&m_{X̮?f1Mɧ|JVL<H5 NQQV#>s2M0I \ No newline at end of file diff --git a/users/tazjin/secrets/secrets.nix b/users/tazjin/secrets/secrets.nix new file mode 100644 index 0000000000..12f12f721c --- /dev/null +++ b/users/tazjin/secrets/secrets.nix @@ -0,0 +1,16 @@ +let + myKeys = import ../keys { }; + allKeys = [ + # local keys + myKeys.tverskoy_ed25519 + myKeys.zamalek_ed25519 + myKeys.khamovnik_agenix + # koptevo + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMw2ZfdNZCXCOtbQNT6hztXCIkTcO9MBrOuDqMlmGOYK root@koptevo" + ]; +in +{ + "geesefs-tazjins-files.age".publicKeys = allKeys; + "miniflux.age".publicKeys = allKeys; + "tgsa-yandex.age".publicKeys = allKeys; +} diff --git a/users/tazjin/secrets/tgsa-yandex.age b/users/tazjin/secrets/tgsa-yandex.age new file mode 100644 index 0000000000..b1400d0673 --- /dev/null +++ b/users/tazjin/secrets/tgsa-yandex.age Binary files differdiff --git a/users/tazjin/tgsa/Cargo.lock b/users/tazjin/tgsa/Cargo.lock index ea9d94f5ee..6be9c490d4 100644 --- a/users/tazjin/tgsa/Cargo.lock +++ b/users/tazjin/tgsa/Cargo.lock @@ -3,25 +3,10 @@ version = 3 [[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] name = "android_system_properties" @@ -34,9 +19,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "ascii" @@ -46,42 +31,33 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] -name = "bitflags" -version = "1.3.2" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "brotli" -version = "3.3.4" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "brotli-decompressor" -version = "2.3.2" +name = "bitflags" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "buf_redux" @@ -95,21 +71,21 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -119,21 +95,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ + "android-tzdata", "iana-time-zone", - "num-integer", "num-traits", - "winapi", + "windows-targets 0.52.4", ] [[package]] name = "chunked_transfer" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" +checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" [[package]] name = "convert_case" @@ -143,18 +119,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "crc32fast" -version = "1.3.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crimp" @@ -181,24 +148,24 @@ dependencies = [ "proc-macro2", "quote", "smallvec", - "syn", + "syn 1.0.109", ] [[package]] name = "cssparser-macros" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn", + "syn 2.0.57", ] [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", @@ -206,14 +173,14 @@ dependencies = [ "openssl-sys", "schannel", "socket2", - "winapi", + "windows-sys", ] [[package]] name = "curl-sys" -version = "0.4.56+curl-7.83.1" +version = "0.4.72+curl-8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093e169dd4de29e468fa649fbae11cdcd5551c81fe5bf1b0677adad7ef3d26f" +checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" dependencies = [ "cc", "libc", @@ -221,17 +188,16 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi", + "windows-sys", ] [[package]] -name = "deflate" -version = "0.9.1" +name = "deranged" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f95bf05dffba6e6cce8dfbb30def788154949ccd9aed761b472119c21e01c70" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ - "adler32", - "gzip-header", + "powerfmt", ] [[package]] @@ -244,20 +210,20 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.109", ] [[package]] name = "dtoa" -version = "0.4.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dtoa-short" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" dependencies = [ "dtoa", ] @@ -269,19 +235,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" [[package]] -name = "fastrand" -version = "1.8.0" +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "instant", + "libc", + "windows-sys", ] [[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] name = "filetime" -version = "0.2.17" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", @@ -290,10 +263,25 @@ dependencies = [ ] [[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -339,9 +327,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -349,22 +337,10 @@ dependencies = [ ] [[package]] -name = "gzip-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0131feb3d3bb2a5a238d8a4d09f6353b7ebfdc52e77bccbf4ea6eaa751dde639" -dependencies = [ - "crc32fast", -] - -[[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "html5ever" @@ -377,7 +353,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -387,35 +363,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] name = "iana-time-zone" -version = "0.1.50" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows-core", ] [[package]] -name = "idna" -version = "0.3.0" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "cc", ] [[package]] -name = "instant" -version = "0.1.12" +name = "idna" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "cfg-if", + "unicode-bidi", + "unicode-normalization", ] [[package]] @@ -426,15 +409,15 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -447,15 +430,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.134" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libz-sys" -version = "1.1.8" +version = "1.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" dependencies = [ "cc", "libc", @@ -464,10 +447,16 @@ dependencies = [ ] [[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -475,12 +464,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "mac" @@ -504,21 +490,21 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -550,9 +536,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nodrop" @@ -561,29 +547,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] -name = "num-integer" -version = "0.1.45" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", @@ -591,18 +573,44 @@ dependencies = [ [[package]] name = "num_threads" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ "libc", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] [[package]] name = "openssl-probe" @@ -612,11 +620,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.76" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -635,22 +642,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-targets 0.48.5", ] [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" @@ -723,7 +730,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -746,15 +753,21 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "precomputed-hash" @@ -764,15 +777,15 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -785,9 +798,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.21" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -852,7 +865,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.12", ] [[package]] @@ -875,41 +888,44 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "ring" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", "winapi", ] [[package]] name = "rouille" -version = "3.5.0" +version = "3.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18b2380c42510ef4a28b5f228a174c801e0dec590103e215e60812e2e2f34d05" +checksum = "3716fbf57fc1084d7a706adf4e445298d123e4a44294c4e8213caf1b85fcc921" dependencies = [ - "base64", - "brotli", + "base64 0.13.1", "chrono", - "deflate", "filetime", "multipart", - "num_cpus", "percent-encoding", "rand 0.8.5", "serde", "serde_derive", "serde_json", - "sha1", + "sha1_smol", "threadpool", "time", "tiny_http", @@ -926,10 +942,23 @@ dependencies = [ ] [[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] name = "ryu" -version = "1.0.11" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "safemem" @@ -939,19 +968,18 @@ checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "lazy_static", "windows-sys", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scraper" @@ -975,7 +1003,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cssparser", "derive_more", "fxhash", @@ -991,34 +1019,37 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", ] [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ - "itoa 1.0.3", + "itoa 1.0.11", "ryu", "serde", ] @@ -1034,15 +1065,6 @@ dependencies = [ ] [[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - -[[package]] name = "sha1_smol" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1050,27 +1072,33 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.4.7" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "winapi", + "windows-sys", ] [[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1078,9 +1106,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "string_cache" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", @@ -1104,9 +1132,20 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.101" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" +checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" dependencies = [ "proc-macro2", "quote", @@ -1115,16 +1154,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys", ] [[package]] @@ -1143,10 +1180,16 @@ name = "tgsa" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.21.7", "crimp", "ego-tree", + "lazy_static", + "openssl", + "ring", "rouille", "scraper", + "serde", + "serde_json", "url", ] @@ -1167,25 +1210,35 @@ dependencies = [ [[package]] name = "time" -version = "0.3.15" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ + "deranged", "libc", + "num-conv", "num_threads", + "powerfmt", + "serde", + "time-core", ] [[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] name = "tiny_http" -version = "0.8.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce51b50006056f590c9b7c3808c3bd70f0d1101666629713866c227d6e58d39" +checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" dependencies = [ "ascii", - "chrono", "chunked_transfer", + "httpdate", "log", - "url", ] [[package]] @@ -1199,9 +1252,9 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "twoway" @@ -1214,45 +1267,51 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "untrusted" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -1291,9 +1350,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1301,24 +1360,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.57", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1326,22 +1385,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "winapi" @@ -1366,44 +1435,133 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] name = "windows-sys" -version = "0.36.1" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/users/tazjin/tgsa/Cargo.toml b/users/tazjin/tgsa/Cargo.toml index 943fe7188e..8764ef6524 100644 --- a/users/tazjin/tgsa/Cargo.toml +++ b/users/tazjin/tgsa/Cargo.toml @@ -6,7 +6,13 @@ edition = "2021" [dependencies] anyhow = "1.0" crimp = "4087.0" -rouille = "3.5" +rouille = { version = "3.5", default-features = false } url = "2.3" scraper = "0.13" ego-tree = "0.6" # in tandem with 'scraper' +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +ring = "0.16.20" +openssl = "0.10.54" +base64 = "0.21.2" +lazy_static = "1.4.0" diff --git a/users/tazjin/tgsa/default.nix b/users/tazjin/tgsa/default.nix index e413c99116..063781047a 100644 --- a/users/tazjin/tgsa/default.nix +++ b/users/tazjin/tgsa/default.nix @@ -1,11 +1,14 @@ { depot, pkgs, ... }: depot.third_party.naersk.buildPackage { - src = depot.nix.sparseTree ./. [ - ./Cargo.lock - ./Cargo.toml - ./src - ]; + src = depot.nix.sparseTree { + root = ./.; + paths = [ + ./Cargo.lock + ./Cargo.toml + ./src + ]; + }; buildInputs = with pkgs; [ pkg-config diff --git a/users/tazjin/tgsa/src/main.rs b/users/tazjin/tgsa/src/main.rs index ed72569f92..d9a5d4abc2 100644 --- a/users/tazjin/tgsa/src/main.rs +++ b/users/tazjin/tgsa/src/main.rs @@ -1,12 +1,16 @@ use anyhow::{anyhow, Context, Result}; +use scraper::{Html, Selector}; use std::collections::HashMap; use std::sync::RwLock; use std::time::{Duration, Instant}; +mod translate; + #[derive(Clone, Debug, Eq, Hash, PartialEq)] struct TgLink { username: String, message_id: usize, + translated: bool, } impl TgLink { @@ -14,12 +18,17 @@ impl TgLink { format!("t.me/{}/{}", self.username, self.message_id) } - fn to_url(&self) -> String { - format!("https://t.me/{}/{}?embed=1", self.username, self.message_id) + fn to_url(&self, embed: bool) -> String { + format!( + "https://t.me/{}/{}{}", + self.username, + self.message_id, + if embed { "?embed=1" } else { "" } + ) } - fn parse(url: &str) -> Option<Self> { - let url = url.strip_prefix("/")?; + fn parse(url: &str, translated: bool) -> Option<Self> { + let url = url.strip_prefix('/')?; let parsed = url::Url::parse(url).ok()?; if parsed.host()? != url::Host::Domain("t.me") { @@ -36,13 +45,14 @@ impl TgLink { Some(TgLink { username: parts[0].into(), message_id: parts[1].parse().ok()?, + translated, }) } } -fn fetch_embed(link: &TgLink) -> Result<String> { +fn fetch_post(link: &TgLink, embed: bool) -> Result<String> { println!("fetching {}#{}", link.username, link.message_id); - let response = crimp::Request::get(&link.to_url()) + let response = crimp::Request::get(&link.to_url(embed)) .send() .context("failed to fetch embed data")? .as_string() @@ -54,6 +64,28 @@ fn fetch_embed(link: &TgLink) -> Result<String> { Ok(response.body) } +// in some cases, posts can not be embedded, but telegram still +// includes their content in metadata tags for content previews. +// +// we skip images in this case, as they are scaled down to thumbnail +// size and not useful. +fn fetch_fallback(link: &TgLink) -> Result<Option<String>> { + let post = fetch_post(link, false)?; + let doc = Html::parse_document(&post); + let desc_sel = Selector::parse("meta[property=\"og:description\"]").unwrap(); + let desc_elem = match doc.select(&desc_sel).next() { + None => return Ok(None), + Some(elem) => elem, + }; + + let content = match desc_elem.value().attr("content") { + None => return Ok(None), + Some(content) => content.to_string(), + }; + + Ok(Some(content)) +} + #[derive(Debug)] struct TgMessage { author: String, @@ -71,8 +103,6 @@ fn extract_photo_url(style: &str) -> Option<&str> { } fn parse_tgmessage(embed: &str) -> Result<TgMessage> { - use scraper::{Html, Selector}; - let doc = Html::parse_document(embed); let author_sel = Selector::parse("a.tgme_widget_message_owner_name").unwrap(); @@ -97,8 +127,8 @@ fn parse_tgmessage(embed: &str) -> Result<TgMessage> { for edge in &mut msg_elem.traverse() { if let Edge::Open(node) = edge { match node.value() { - Node::Text(ref text) => out.push_str(&*text), - Node::Element(elem) if elem.name() == "br" => out.push_str("\n"), + Node::Text(ref text) => out.push_str(text), + Node::Element(elem) if elem.name() == "br" => out.push('\n'), _ => {} } } @@ -164,7 +194,7 @@ fn to_bbcode(link: &TgLink, msg: &TgMessage) -> String { out.push_str(&format!("[quote=\"{}\"]\n", msg.author)); for video in 0..msg.videos.len() { - out.push_str(&format!("[url=\"{}\"]", link.to_url())); + out.push_str(&format!("[url=\"{}\"]", link.to_url(true))); // video thumbnail links are appended to the photos, hence the // addition here @@ -184,7 +214,7 @@ fn to_bbcode(link: &TgLink, msg: &TgMessage) -> String { if msg.has_audio { out.push_str(&format!( "[i]This message has audio attached. Go [url=\"{}\"]to Telegram[/url] to listen.[/i]", - link.to_url(), + link.to_url(true), )); } @@ -196,7 +226,7 @@ fn to_bbcode(link: &TgLink, msg: &TgMessage) -> String { out.push_str(&format!( "[sub](from [url=\"{}\"]{}[/url], via [url=\"https://tgsa.tazj.in\"]tgsa[/url])[/sub]\n", - link.to_url(), + link.to_url(true), link.human_friendly_url(), )); @@ -216,7 +246,7 @@ struct TgPost { type Cache = RwLock<HashMap<TgLink, TgPost>>; fn fetch_with_cache(cache: &Cache, link: &TgLink) -> Result<TgPost> { - if let Some(entry) = cache.read().unwrap().get(&link) { + if let Some(entry) = cache.read().unwrap().get(link) { if Instant::now() - entry.at < CACHE_EXPIRY { println!("serving {}#{} from cache", link.username, link.message_id); return Ok(entry.clone()); @@ -227,9 +257,21 @@ fn fetch_with_cache(cache: &Cache, link: &TgLink) -> Result<TgPost> { // TODO(tazjin): per link? let mut writer = cache.write().unwrap(); - let embed = fetch_embed(&link)?; - let mut msg = parse_tgmessage(&embed)?; - let bbcode = to_bbcode(&link, &msg); + let post = fetch_post(link, true)?; + let mut msg = parse_tgmessage(&post)?; + + if msg.message.is_none() { + msg.message = fetch_fallback(link)?; + } + + if let Some(message) = &msg.message { + if link.translated { + println!("translating {}#{}", link.username, link.message_id); + msg.message = Some(translate::fetch_translation(message)?); + } + } + + let bbcode = to_bbcode(link, &msg); let mut media = vec![]; media.append(&mut msg.photos); @@ -256,7 +298,7 @@ fn handle_img_redirect(cache: &Cache, img_path: &str) -> Result<rouille::Respons // | post ID // username - let img_parts: Vec<&str> = img_path.split("/").collect(); + let img_parts: Vec<&str> = img_path.split('/').collect(); if img_parts.len() != 3 { println!("invalid image link: {}", img_path); @@ -266,6 +308,7 @@ fn handle_img_redirect(cache: &Cache, img_path: &str) -> Result<rouille::Respons let link = TgLink { username: img_parts[0].into(), message_id: img_parts[1].parse().context("failed to parse message_id")?, + translated: false, }; let img_idx: usize = img_parts[2].parse().context("failed to parse img_idx")?; @@ -294,12 +337,20 @@ fn main() { let cache: Cache = RwLock::new(HashMap::new()); rouille::start_server("0.0.0.0:8472", move |request| { + let mut raw_url = request.raw_url(); + let mut translate = false; + let response = loop { - if request.raw_url().starts_with("/img/") { - break handle_img_redirect(&cache, &request.raw_url()[5..]); + if raw_url.starts_with("/img/") { + break handle_img_redirect(&cache, &raw_url[5..]); } - break match TgLink::parse(request.raw_url()) { + if raw_url.starts_with("/translate/") { + translate = true; + raw_url = &raw_url[10..]; + } + + break match TgLink::parse(raw_url, translate) { None => Ok(rouille::Response::text( r#"tgsa ---- @@ -319,7 +370,16 @@ yes, that looks stupid, but it works if you see this message and think you did the above correctly, you didn't. try again. idiot. -pm me on the forums if this makes you mad or something. +it can also translate posts from russian, ukrainian or whatever other +dumb language you speak into english by adding `/translate/`, for +example: + + https://tgsa.tazj.in/translate/https://t.me/strelkovii/4329 + +expect this to be slow though. that's the price to pay for translating +shitty slang. + +pm me on the forums if any of this makes you mad or something. "#, )), Some(link) => handle_tg_link(&cache, &link), diff --git a/users/tazjin/tgsa/src/translate.rs b/users/tazjin/tgsa/src/translate.rs new file mode 100644 index 0000000000..35d7b35ca8 --- /dev/null +++ b/users/tazjin/tgsa/src/translate.rs @@ -0,0 +1,191 @@ +//! integration with yandex cloud translate api, for automatically +//! translating telegram posts. +//! +//! most of this module is concerned with handling the authentication +//! tokens for yandex cloud, as jwt signing needs to be handled +//! manually (none of the rust jwt libraries that i tried actually +//! work). + +use anyhow::{anyhow, Context, Result}; +use base64::prelude::BASE64_URL_SAFE_NO_PAD as B64; +use base64::Engine; +use lazy_static::lazy_static; +use ring::signature as sig; +use serde::Deserialize; +use serde_json::{json, Value}; +use std::sync::Mutex; +use std::time::{Duration, SystemTime}; + +/// token exchange url (exchanging a signed jwt for an iam token +/// understood by the translation service) +const TOKEN_URL: &str = "https://iam.api.cloud.yandex.net/iam/v1/tokens"; + +/// translation endpoint +const TRANSLATE_URL: &str = "https://translate.api.cloud.yandex.net/translate/v2/translate"; + +/// describes the private key as downloaded from yandex, pem-encoded. +#[derive(Deserialize)] +struct AuthorizedKey { + id: String, + service_account_id: String, + private_key: String, +} + +/// cached iam token for yandex cloud +struct Token { + token: String, + expiry: SystemTime, +} + +impl Token { + fn is_expired(&self) -> bool { + self.expiry < SystemTime::now() + } +} + +lazy_static! { + static ref KEY_FILE: String = + std::env::var("YANDEX_KEY_FILE").expect("`YANDEX_KEY_FILE` variable should be set"); + static ref CACHED_TOKEN: Mutex<Token> = { + let token = refresh_token().expect("fetching initial translation token must not fail"); + Mutex::new(token) + }; +} + +/// wrap all the authentication logic below into a single function. +fn refresh_token() -> Result<Token> { + let file = std::fs::File::open(KEY_FILE.as_str())?; + let key: AuthorizedKey = serde_json::from_reader(file)?; + let jwt = sign_yandex_jwt(&key)?; + let token = fetch_iam_token(&jwt)?; + + Ok(Token { + token, + expiry: SystemTime::now() + Duration::from_secs(3600), + }) +} + +/// wrapper around the cached token that refreshes if required. +fn current_token() -> Result<String> { + let mut token = CACHED_TOKEN + .lock() + .expect("thread operating on token should never fail"); + + if token.is_expired() { + println!("refreshing translation token"); + *token = refresh_token().context("refreshing translation token")?; + } + + Ok(token.token.clone()) +} + +/// use openssl to read the pem-encoded key, as ring itself is not +/// capable of this. +fn read_pem_key(key: &AuthorizedKey) -> Result<sig::RsaKeyPair> { + let rsa = openssl::rsa::Rsa::private_key_from_pem(key.private_key.as_bytes()) + .context("parsing RSA key")?; + + let der = rsa + .private_key_to_der() + .context("encoding key as DER for ring")?; + + sig::RsaKeyPair::from_der(&der).map_err(|err| anyhow!("decoding DER key in ring: {}", err)) +} + +/// manually construct and sign the jwt required to perform the +/// iam-token key exchange with yandex. +fn sign_yandex_jwt(key: &AuthorizedKey) -> Result<String> { + let iat = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs(); + + let header = json!({ + "typ": "JWT", + "alg": "PS256", + "kid": key.id, + }) + .to_string(); + + let payload = json!({ + "iss": key.service_account_id, + "aud": TOKEN_URL, + "iat": iat, + "exp": iat + 60, + }) + .to_string(); + + let unsigned = format!("{}.{}", B64.encode(header), B64.encode(payload)); + let key_pair = read_pem_key(key)?; + + let rng = ring::rand::SystemRandom::new(); + let mut signature = vec![0; key_pair.public_modulus_len()]; + key_pair + .sign( + &sig::RSA_PSS_SHA256, + &rng, + unsigned.as_bytes(), + &mut signature, + ) + .map_err(|err| anyhow!("while signing JWT: {}", err))?; + + Ok(format!("{}.{}", unsigned, B64.encode(&signature))) +} + +/// exchange the jwt for an iam token +fn fetch_iam_token(token: &str) -> Result<String> { + #[derive(Deserialize)] + #[serde(rename_all = "camelCase")] + struct TokenResponse { + iam_token: String, + } + + let response = crimp::Request::post(TOKEN_URL) + .json(&json!({ + "jwt": token, + }))? + .send()? + .error_for_status(|resp| { + anyhow::anyhow!("{} ({})", String::from_utf8_lossy(&resp.body), resp.status) + })? + .as_json::<TokenResponse>() + .context("deserialising IAM token")?; + + Ok(response.body.iam_token) +} + +pub fn fetch_translation(message: &str) -> Result<String> { + let request_body = json!({ + "folderId": "b1g5k8f0tgimg06i6p5h", + "texts": [ message ], + "targetLanguageCode": "en", + }); + + let response = crimp::Request::post(TRANSLATE_URL) + .bearer_auth(¤t_token()?) + .context("adding 'Bearer' token")? + .json(&request_body) + .context("preparing JSON body")? + .send() + .context("failed to fetch translation from yandex")? + .error_for_status(|resp| { + anyhow!( + "translation request failed: {} ({})", + String::from_utf8_lossy(&resp.body), + resp.status + ) + })? + .as_json::<Value>()? + .body; + + let translation = response + .get("translations") + .ok_or_else(|| anyhow!("missing 'translations' key"))? + .get(0) + .ok_or_else(|| anyhow!("translations list is empty"))? + .get("text") + .ok_or_else(|| anyhow!("translation missing 'text' key"))? + .as_str() + .ok_or_else(|| anyhow!("'text' was not a string"))?; + + Ok(translation.to_string()) +} diff --git a/users/tazjin/tvix-eval-value.d2 b/users/tazjin/tvix-eval-value.d2 new file mode 100644 index 0000000000..dad2dbcef2 --- /dev/null +++ b/users/tazjin/tvix-eval-value.d2 @@ -0,0 +1,98 @@ +# D2 diagram of tvix-eval's `Value` type. +# +# can be rendered at https://play.d2lang.com/ +# +# colours have meanings: +# +# yellow: recurses +# orange: heap allocation +# red: refcount +# +# this intentionally does *not* include some internal variants + +Value -> Null +Value -> Bool +Value -> Integer +Value -> Float + +Box*.style.fill: "lightsalmon" +Rc*.style.fill: "salmon" +Vec\<*.style.fill: "salmon" + +Value -> String -> NixString -> "Box<str>" + +Value -> Path -> "Box<PathBuf>" -> PathBuf +PathBuf.style.fill: "lightsalmon" + +# attribute sets are kinda complicated +Value -> Attrs -> "Box<NixAttrs>" -> NixAttrs +NixAttrs -> Empty +NixAttrs -> KV +KV.style.fill: "LemonChiffon" +KV -> Value +KV -> Value +NixAttrs -> Map +Map -> "OrdMap<NixString, Value>" -> "MapEntry<NixString, Value>" +"OrdMap<NixString, Value>".style.fill: "lightsalmon" +"MapEntry<NixString, Value>".style.fill: "salmon" +"MapEntry<NixString, Value>".style.multiple: true +"MapEntry<NixString, Value>" -> NixString +"MapEntry<NixString, Value>" -> Value +"MapEntry<NixString, Value>".style.stroke-width: 15 +"MapEntry<NixString, Value>".style.stroke: "lemonchiffon" + +Value -> List -> NixList -> "Rc<imbl::Vector<Value>>" +"Rc<imbl::Vector<Value>>" -> "VecEntry<Value>" -> Value +"VecEntry<Value>".style.multiple: true +"VecEntry<Value>".style.fill: "salmon" +"VecEntry<Value>".style.stroke-width: 15 +"VecEntry<Value>".style.stroke: "lemonchiffon" + +# closures + +Value -> Closure -> "Rc<Closure>" -> Closure +Closure -> "Rc<Lambda>" -> Lambda + +Lambda -> Chunk +Lambda -> SmolStr: sometimes allocates +SmolStr.style.fill: "lightsalmon" +Lambda -> usize +Lambda -> "Option<Formals>" -> Formals + +Formals -> "HashMap<NixString, bool>" -> "MapEntry<NixString, bool>" +"HashMap<NixString, bool>".style.fill: "lightsalmon" +"MapEntry<NixString, bool>".style.fill: "salmon" +"MapEntry<NixString, bool>".style.multiple: true +"MapEntry<NixString, bool>" -> NixString + +Closure -> "Rc<Upvalues>" -> Upvalues + +Upvalues -> "Vec<Value>" +"Vec<Value>" -> Value +"Vec<Value>".style.stroke-width: 15 +"Vec<Value>".style.stroke: "lemonchiffon" +Upvalues -> "Option<Vec<Value>>" +"Option<Vec<Value>>" -> Value +"Option<Vec<Value>>".style.fill: "lightsalmon" +"Option<Vec<Value>>".style.stroke-width: 15 +"Option<Vec<Value>>".style.stroke: "lemonchiffon" + +Value -> Blueprint -> "Rc<Lambda>" + +# builtins + +Value -> Builtin -> "Box<BuiltinRepr>" -> BuiltinRepr +BuiltinRepr -> "Rc<dyn BuiltinGen>" +BuiltinRepr -> "Vec<Value>" + +# thunks + +Value -> Thunk -> "Rc<RefCell<ThunkRepr>>" -> ThunkRepr +ThunkRepr -> Suspended +Suspended -> "Rc<Lambda>" +Suspended -> "Rc<Upvalues>" + +ThunkRepr -> Native -> "Box<dyn Fn() -> Result<Value, ErrorKind>>" +ThunkRepr -> Blackhole +ThunkRepr -> Evaluated -> Value +Evaluated.style.fill: "lemonchiffon" diff --git a/users/tazjin/yddns/.gitignore b/users/tazjin/yddns/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/users/tazjin/yddns/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/users/tazjin/yddns/Cargo.lock b/users/tazjin/yddns/Cargo.lock new file mode 100644 index 0000000000..58b37d553b --- /dev/null +++ b/users/tazjin/yddns/Cargo.lock @@ -0,0 +1,1425 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crimp" +version = "4087.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ead2c83f7d1f9b8e5a6f7a25985d0d1759ccd2cd72abb1eee2db65d05e12b39" +dependencies = [ + "curl", + "serde", + "serde_json", +] + +[[package]] +name = "curl" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2 0.4.10", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.68+curl-8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "windows-sys", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "http" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f95b9abcae896730d42b78e09c155ed4ddf82c07b4de772c64aee5b2d8b7c150" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "rustls-native-certs", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "yandex-cloud" +version = "2023.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98f67140264e8e090e26b70925096adf295569c057a8b2ad2cd7e0f10c01cfae" +dependencies = [ + "prost", + "prost-types", + "tonic", + "tonic-build", + "walkdir", +] + +[[package]] +name = "yddns" +version = "0.1.0" +dependencies = [ + "anyhow", + "crimp", + "tokio", + "yandex-cloud", +] diff --git a/users/tazjin/yddns/Cargo.toml b/users/tazjin/yddns/Cargo.toml new file mode 100644 index 0000000000..78691f303d --- /dev/null +++ b/users/tazjin/yddns/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "yddns" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0" +crimp = "4087.0" +tokio = "*" # pulled in by yandex-cloud +yandex-cloud = "2023.6.13" diff --git a/users/tazjin/yddns/default.nix b/users/tazjin/yddns/default.nix new file mode 100644 index 0000000000..40b0d1c24e --- /dev/null +++ b/users/tazjin/yddns/default.nix @@ -0,0 +1,9 @@ +{ depot, pkgs, ... }: + +depot.third_party.naersk.buildPackage { + src = ./.; + buildInputs = with pkgs; [ + pkg-config + openssl + ]; +} diff --git a/users/tazjin/yddns/src/main.rs b/users/tazjin/yddns/src/main.rs new file mode 100644 index 0000000000..2e2f9fe02f --- /dev/null +++ b/users/tazjin/yddns/src/main.rs @@ -0,0 +1,142 @@ +use anyhow::{anyhow, bail, Context, Result}; +use crimp::Request; +use std::env; +use std::net::Ipv4Addr; +use tokio::runtime; +use yandex_cloud::tonic_exports::{Channel, Endpoint, InterceptedService}; +use yandex_cloud::yandex::cloud::dns::v1 as dns; +use yandex_cloud::yandex::cloud::dns::v1::dns_zone_service_client::DnsZoneServiceClient; +use yandex_cloud::{AuthInterceptor, TokenProvider}; + +type DnsClient<T> = DnsZoneServiceClient<InterceptedService<Channel, AuthInterceptor<T>>>; + +/// Fetch the current IP from the given URL. It should be the URL of a +/// site that responds only with the IP in plain text, and nothing else. +fn get_current_ip(source: &str) -> Result<Ipv4Addr> { + let response = Request::get(source) + .send() + .context("failed to fetch current IP")? + .error_for_status(|resp| anyhow!("error response ({})", resp.status)) + .context("received error response for IP")? + .as_string()? + .body; + + Ok(response.trim().parse().with_context(|| { + format!( + "failed to parse IP address from response body: {}", + response + ) + })?) +} + +/// Fetch the current address of the target record. +async fn fetch_current_record_addr<T: TokenProvider>( + client: &mut DnsClient<T>, + zone_id: &str, + record_name: &str, +) -> Result<Ipv4Addr> { + let req = dns::GetDnsZoneRecordSetRequest { + dns_zone_id: zone_id.into(), + name: record_name.into(), + r#type: "A".into(), + }; + + let response = client + .get_record_set(req) + .await + .context("failed to fetch current record set")? + .into_inner(); + + if response.data.len() != 1 { + bail!( + "expected exactly one record for 'A {}', but found {}", + record_name, + response.data.len() + ); + } + + Ok(response.data[0] + .parse() + .context("failed to parse returned record")?) +} + +/// Update the record with the new address, if required. +async fn update_record<T: TokenProvider>( + client: &mut DnsClient<T>, + zone_id: &str, + record_name: &str, + new_address: Ipv4Addr, +) -> Result<()> { + let request = dns::UpsertRecordSetsRequest { + dns_zone_id: zone_id.into(), + replacements: vec![dns::RecordSet { + name: record_name.into(), + r#type: "A".into(), + ttl: 3600, // 1 hour + data: vec![new_address.to_string()], + }], + ..Default::default() + }; + + client + .upsert_record_sets(request) + .await + .context("failed to update record")?; + + Ok(()) +} + +/// Compare the record with the expected value, and issue an update if +/// necessary. +async fn compare_update_record<T: TokenProvider>( + client: &mut DnsClient<T>, + zone_id: &str, + record_name: &str, + new_ip: Ipv4Addr, +) -> Result<()> { + let old_ip = fetch_current_record_addr(client, zone_id, record_name).await?; + + if old_ip == new_ip { + println!("IP address unchanged ({})", old_ip); + return Ok(()); + } + + println!( + "IP address changed: current record points to {}, but address is {}", + old_ip, new_ip + ); + + update_record(client, zone_id, record_name, new_ip).await?; + println!("successfully updated '{}' to 'A {}'", record_name, new_ip); + + Ok(()) +} + +fn main() -> Result<()> { + let token = + env::var("YANDEX_CLOUD_TOKEN").context("Yandex Cloud authentication token unset")?; + let target_zone_id = + env::var("TARGET_ZONE").unwrap_or_else(|_| "dnsd0tif5mokfu0mg8i5".to_string()); + let target_record = env::var("TARGET_RECORD").unwrap_or_else(|_| "khtrsk".to_string()); + + let current_ip = get_current_ip("http://ifconfig.me")?; + println!("current IP address is '{}'", current_ip); + + let rt = runtime::Builder::new_current_thread() + .enable_time() + .enable_io() + .build()?; + + rt.block_on(async move { + let channel = Endpoint::from_static("https://dns.api.cloud.yandex.net") + .connect() + .await?; + + let mut client = + DnsZoneServiceClient::with_interceptor(channel, AuthInterceptor::new(token)); + + compare_update_record(&mut client, &target_zone_id, &target_record, current_ip).await + })?; + + Ok(()) +} |