Compare commits

..

302 Commits

Author SHA1 Message Date
e89805cd17 sxmo: have sway launch sxmo -- not the other way around
this lets me treat sxmo as just some nice scripts which run atop an existing DE (sway), rather than the opposite

can share more code with my desktop/laptop
2023-09-04 11:10:30 +00:00
680ab2c189 lappy: fix sxmo polyfill 2023-09-04 10:01:29 +00:00
10095e3ce5 sxmo: rename greeter option: {,->greetd-}sway-gtkgreet 2023-09-04 01:06:57 +00:00
a2b8e23eee nixpkgs: 2023-09-01 -> 2023-09-02
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/aa8aa7e2ea35ce655297e8322dc82bf77a31d04b' (2023-09-01)
  → 'github:nixos/nixpkgs/e56990880811a451abd32515698c712788be5720' (2023-09-02)
```
2023-09-03 20:13:07 +00:00
0587c14af5 nixpkgs: 2023-08-31 -> 2023-09-01
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/3e52e76b70d5508f3cec70b882a29199f4d1ee85' (2023-08-31)
  → 'github:nixos/nixpkgs/aa8aa7e2ea35ce655297e8322dc82bf77a31d04b' (2023-09-01)
```
2023-09-03 08:49:56 +00:00
6a83e0ce6c WIP: sxmo: ship notifications-related dependencies 2023-09-03 08:48:43 +00:00
72960aa963 cross: fix flatpak compilation 2023-09-03 08:46:50 +00:00
5f4f047769 cross: fix ostree compilation 2023-09-03 07:45:21 +00:00
a880ba254b sway: remove some unneeded config options 2023-09-02 10:37:09 +00:00
4d75c3d97a ejabberd: document more compat & how to admin 2023-09-02 08:36:32 +00:00
90511ed765 ejabberd: support matrix: clarify client support 2023-09-02 08:36:32 +00:00
aa3b85511f ejabberd: docs: update federation/support matrix 2023-09-02 08:36:32 +00:00
5d90cbcc98 programs: ship gajim on desko 2023-09-02 07:21:16 +00:00
0525f99813 moby: ship dino 2023-09-02 05:13:01 +00:00
769019f2f5 greetd: types.string -> types.str 2023-09-02 01:36:11 +00:00
dcaba0f0ee secrets: fix build when host has no secrets 2023-09-02 01:34:32 +00:00
d33b6eec59 flake: add a check-host-configs target to ensure all hosts are buildable 2023-09-02 01:25:20 +00:00
20aef83496 greetd: refactor: session{Name,Cmd,User} into session attrset 2023-09-02 00:54:05 +00:00
3cc4a1ea19 sxmo: port to greetd abstraction 2023-09-02 00:49:44 +00:00
a41fefa906 consolidate greetd stuff out of sway 2023-09-02 00:07:46 +00:00
c00bba3fcf nixpkgs: 2023-08-30 -> 2023-08-31
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/e7f38be3775bab9659575f192ece011c033655f0' (2023-08-30)
  → 'github:nixos/nixpkgs/3e52e76b70d5508f3cec70b882a29199f4d1ee85' (2023-08-31)
```
2023-09-01 20:03:55 +00:00
63fab5899b common: mount /mnt/servo-nfs/playground 2023-09-01 10:10:28 +00:00
357b6ef06e nfs: expose playground as a read/write dir 2023-09-01 10:08:29 +00:00
4fdf74fdbe export: enforce a quota 2023-09-01 03:37:33 +00:00
15e09573d5 exports: consolidate nfs and sftpgo mounts into /var/export 2023-09-01 01:23:35 +00:00
d6479ca148 nfs/sftpgo: combine into "exports" nix directory 2023-09-01 00:39:22 +00:00
cf9558f166 WIP: sftp: define playground as a btrfs subvolume 2023-09-01 00:35:43 +00:00
68bce9c8b7 ports: if they fail to forward, retry after some interval 2023-09-01 00:30:32 +00:00
913201b9cd sane-bt-search: add TPB to TRACKER_RANKS 2023-08-31 23:38:29 +00:00
3f748164e4 ftp: add a playground directory 2023-08-31 12:56:30 +00:00
ded5d94d69 modules: fs: add a "text" type to populate static text files when symlinks wont do 2023-08-31 12:56:30 +00:00
815a8b52b6 refactor: sftpgo: define permissions via nix config 2023-08-31 12:56:30 +00:00
639a4cfe50 ftp: grant read access to LAN 2023-08-31 12:56:30 +00:00
b2af4e8983 nixpkgs: disable phog patch 2023-08-31 12:56:09 +00:00
ff39fc5d95 ports: make upnp service files more human-readable 2023-08-31 01:02:48 +00:00
9fea007d4f cross: support gnome "calls" package 2023-08-31 00:52:28 +00:00
f44a094d1d nixpkgs: 2023-08-28 -> 2023-08-30; sops-nix -> 2023-08-30
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/3efb0f6f404ec8dae31bdb1a9b17705ce0d6986e' (2023-08-28)
  → 'github:nixos/nixpkgs/e7f38be3775bab9659575f192ece011c033655f0' (2023-08-30)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/c89ee06488706b587a22085b1844bf9ca6ba5687' (2023-08-28)
  → 'github:Mic92/sops-nix/d9c5dc41c4b1f74c77f0dbffd0f3a4ebde447b7a' (2023-08-30)
```
2023-08-30 20:45:57 +00:00
ec6f90eb44 mpv: fix "DRM_IOCTL_MODE_CREATE_DUMB failed" bug 2023-08-30 10:32:31 +00:00
bbe583637f mpv: uosc: 2023-07-26 -> 2023-08-29 2023-08-30 06:33:09 +00:00
29eab151a1 lemoa: 0.3 -> 0.4 2023-08-30 05:34:04 +00:00
a7c5daf8a5 sxmo: sway-config: leave a todo for deploying via /etc/sway/config.d 2023-08-30 01:56:32 +00:00
a23dea03a9 sxmo: sway config: pull defaults from upstream sxmo-utils 2023-08-30 01:54:30 +00:00
45e5f3ecca dino: document how to start calls 2023-08-30 01:50:06 +00:00
8bcba8802f sxmo-utils: 2023-08-22 -> 2023-08-29 2023-08-30 01:49:48 +00:00
3e2e0ccc1c nixpatches: note to split xdg-utils patch 2023-08-29 21:26:43 +00:00
c14d88f1ea nixpkgs: 2023-08-27 -> 2023-08-28
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/a999c1cc0c9eb2095729d5aa03e0d8f7ed256780' (2023-08-27)
  → 'github:nixos/nixpkgs/3efb0f6f404ec8dae31bdb1a9b17705ce0d6986e' (2023-08-28)
```
2023-08-29 21:26:43 +00:00
e72e847147 sops-nix: 2023-08-27 -> 2023-08-28 2023-08-29 21:26:43 +00:00
073879e523 nixpkgs: 2023-08-25 -> 2023-08-27
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/5690c4271f2998c304a45c91a0aeb8fb69feaea7' (2023-08-25)
  → 'github:nixos/nixpkgs/a999c1cc0c9eb2095729d5aa03e0d8f7ed256780' (2023-08-27)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/1b7b3a32d65dbcd69c217d7735fdf0a6b2184f45' (2023-08-22)
  → 'github:Mic92/sops-nix/0618c8f0ed5255ad74ee08d1618841ff5af85c86' (2023-08-27)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/5e63e8bbc46bc4fc22254da1edaf42fc7549c18a' (2023-08-20)
  → 'github:NixOS/nixpkgs/9117c4e9dc117a6cd0319cca40f2349ed333669d' (2023-08-27)
```
2023-08-29 21:26:43 +00:00
bf302f70f1 servo: ejabberd: give each TURN port a unique upnp description
i think some impls expect the description to be unique?
2023-08-29 11:46:40 +00:00
a045eaa181 sxmo: persist the fontconfig and mesa_shader_cache directories for faster boot 2023-08-29 10:35:14 +00:00
b83b2ce0cc sxmo-utils: begin to push Makefile patches upstream 2023-08-29 10:32:56 +00:00
377aec7e07 sxmo-utils: re-add lost patch to the stable variant 2023-08-29 10:09:30 +00:00
9d50a6669a sxmo-utils-latest: 2023-08-11 -> 2023-08-22 2023-08-29 10:00:42 +00:00
bded6c9562 todo.md: new entry for getting sxmo youtube script working 2023-08-29 09:44:52 +00:00
5520c74921 sxmo-utils: add missing wl-clipboard dependency (for sxmo_screenshot.sh) 2023-08-29 09:44:30 +00:00
589c005bc4 sxmo-utils: add missing slurp dependency 2023-08-29 09:17:09 +00:00
d64a213ec2 sxmo-utils: add missing wtype package 2023-08-29 08:49:25 +00:00
18c940962e sxmo-utils: fix incorrect PREFIX
this should help the appscripts (screenshotting and the like)
2023-08-29 07:59:43 +00:00
e01b1f35fc sxmo-utils: simplifiy the install phase 2023-08-29 07:35:42 +00:00
60030860e5 todo.md: sxmo: better dependency/PATH handling 2023-08-29 07:35:42 +00:00
90894087e5 sxmo: apply SXMO_DISABLE_CONFIGVERSION_CHECK earlier 2023-08-29 07:35:42 +00:00
bdcccbd894 ejabberd: forward TURN ports over UPnP 2023-08-29 07:22:48 +00:00
b64cf408fb chatty: persist all of ~/.purple 2023-08-29 06:13:24 +00:00
eaca5b9889 cross: record more upstreaming status 2023-08-29 00:18:07 +00:00
1c265b2073 cross: update upstreaming status 2023-08-28 23:33:42 +00:00
fa98ba86bc sxmo: default SXMO_DISABLE_CONFIGVERSION_CHECK to on 2023-08-28 21:53:43 +00:00
53aee9e651 cross: libgweather/tuba: grab from upstream PRs 2023-08-28 12:04:03 +00:00
d4a305f5bb cross: tuba: grab from nixpkgs fork 2023-08-28 11:52:39 +00:00
fd39efe31f sxmo-utils: sxmo_hook_apps: fix some typod apps 2023-08-28 11:15:25 +00:00
3b2f4b6f72 preferences: phog: fix eval typo 2023-08-28 11:15:05 +00:00
9a16942b16 cross: send brightnessctl, libgweather (partially) upstream 2023-08-28 11:14:51 +00:00
fe47d68fd3 sxmo-utils: disable configversion checking
this is not yet deployed -- might not work 100%
2023-08-28 10:32:37 +00:00
deaee833cf cross: move phog patch to preferences.nix 2023-08-28 10:08:50 +00:00
8d03881109 cross compilation: disable kitty patch (no longer needed) 2023-08-28 10:06:24 +00:00
e476adfdf5 todo.md: add entry for fixing fonts in wvkbd 2023-08-28 09:56:24 +00:00
4201aa7466 gui: sxmo: default to sxmo-utils-latest variant of the package 2023-08-28 09:56:02 +00:00
a85d594c89 sxmo-utils: add a few more apps i use 2023-08-28 09:55:34 +00:00
7b98cd3d50 todo.md: remove completed phog item 2023-08-28 09:37:01 +00:00
d256a0b647 todo.md: upstreaming to non-nixpkgs 2023-08-28 09:36:11 +00:00
c87ba7f670 snippets: add link to sxmo-devel maillist 2023-08-28 09:26:41 +00:00
e4e5df80f1 sxmo-utils: factor out commons and create a package for sxmo-utils-latest 2023-08-28 09:26:30 +00:00
02f409451d chatty: persist .purple/chatty 2023-08-28 09:01:29 +00:00
9f2c7b90ce snippets.txt: more uninsane services; Johoe mempool 2023-08-28 08:52:33 +00:00
559c551752 re-enable dino XMPP client 2023-08-28 08:48:35 +00:00
304482cc9b moby: ModemManager: make quieter 2023-08-28 08:09:19 +00:00
ad9db91812 moby: ship eg25-control on user profile 2023-08-28 08:03:27 +00:00
1c7997e1ef rename eg25-control-defaults.service -> eg25-control 2023-08-28 08:03:14 +00:00
deefcaae9a nixpkgs: 2023-08-24 -> 2023-08-25
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/18324978d632ffc55ef1d928e81630c620f4f447' (2023-08-24)
  → 'github:nixos/nixpkgs/5690c4271f2998c304a45c91a0aeb8fb69feaea7' (2023-08-25)
```
2023-08-26 20:07:04 +00:00
562008f3c0 sxmo: default to greetd + sway + phog greeter 2023-08-26 19:57:43 +00:00
2584d62b28 sxmo: enable hardware opengl
this fixes the awful perf i was seeing when not using lightdm-mobile-greeter

xserver enables hardware opengl, i'm just copying that behavior to non-X greeters
2023-08-26 19:57:43 +00:00
dc64193a62 moby: generalize sun4i init failure to displayManager *and* greetd 2023-08-26 19:57:43 +00:00
a7f8089ed8 sane-bt-search: link to jargon definitions 2023-08-26 19:25:23 +00:00
e8e63167d2 phog: bring in-tree and patch to allow launching via sway
it looses the bar functionality (oh well)
2023-08-26 13:04:07 +00:00
c056191de1 sxmo: try some alternate greeters 2023-08-26 12:28:25 +00:00
f2a597f698 moby: sxmo: phog: provide an identifier in the syslog 2023-08-26 10:06:36 +00:00
7b637f976b moby: sxmo: fix phog to log its output 2023-08-26 09:40:07 +00:00
39a378c517 nixpkgs: 2023-08-22 -> 2023-08-24
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/b85ed9dcbf187b909ef7964774f8847d554fab3b' (2023-08-22)
  → 'github:nixos/nixpkgs/18324978d632ffc55ef1d928e81630c620f4f447' (2023-08-24)
```
2023-08-26 01:26:33 +00:00
0f9dfb9f8a sxmo-utils: add missing xrdb dependency 2023-08-25 23:37:05 +00:00
ab7f2fb1ec sxmo: switch back to lightdm-mobile greeter 2023-08-25 23:36:47 +00:00
a892c364c6 sxmo-utils: cherry-pick upstream light -> brightnessctl patch 2023-08-25 22:33:48 +00:00
a5c829fa96 moby: switch to phog by default 2023-08-25 13:29:49 +00:00
e844cf5970 phog: fix hardcoded paths 2023-08-25 13:29:29 +00:00
999c6fd880 preferences: remove a dead todo 2023-08-25 12:14:03 +00:00
2aa4bdd5a6 cross compilation: fix brightnessctl 2023-08-25 12:13:39 +00:00
05801f298f phog: add missing gnome-shell dependency
oof, that's a massive dep to pull in just for the schema files...
2023-08-25 12:05:15 +00:00
0fd1ec861b sxmo-utils: add missing brightnessctl dep 2023-08-25 12:04:28 +00:00
37d0473b7f cross: enable gnome-clocks, gnome-shell, squeekboard, better libgweather 2023-08-25 12:03:35 +00:00
aaca46c485 cross: get ibus to cross-compile 2023-08-25 12:01:49 +00:00
30a6a1c1c2 new todo: fix mpv blank UI bug 2023-08-25 01:34:19 +00:00
2c39ac3015 phoc: remove patches; they've been upstreamed 2023-08-25 01:33:34 +00:00
cc6a0dd8b3 phoc: fix patching style to be better overridable 2023-08-25 01:32:45 +00:00
fbf62f0531 moby: add experimental support for phog greeter 2023-08-25 01:25:07 +00:00
c96b951895 todo.md: moby: switch to phog greeter 2023-08-24 21:31:28 +00:00
34294341d7 libgweather: update nws patch with PR feedback 2023-08-24 11:41:31 +00:00
cdc8885e60 sane-weather: leave notes for future work 2023-08-24 11:23:33 +00:00
41416cd184 moby: conky: tune weather display 2023-08-24 11:17:36 +00:00
3c32246d9a sane-weather: default to METAR only 2023-08-24 11:06:24 +00:00
6862d084ac sane-weather: format the temperature better 2023-08-24 11:06:05 +00:00
6eb3626203 ship gnome-weather to all GUI platforms 2023-08-24 11:00:38 +00:00
5f808eab5c libgweather: push NWS segfault fix upstream 2023-08-24 10:35:54 +00:00
fe15c0b097 sane-weather: switch to METAR + NWS
NWS gets us hourly forecasts
2023-08-24 09:20:36 +00:00
e4fbe9d03c sane-weather: reoder the operations list 2023-08-24 09:20:36 +00:00
de09d54c64 sane-weather: make the location configurable 2023-08-24 09:20:36 +00:00
5bf117fc05 sane-weather: document some functions/classes 2023-08-24 09:20:36 +00:00
f734797628 libgweather: fix null string comparison in nws backend 2023-08-24 09:20:36 +00:00
236470dc33 cross compilation fixes for previous nixpkgs update 2023-08-24 05:56:47 +00:00
555627dad5 nixpkgs: 2023-08-21 -> 2023-08-22
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/91a22f76cd1716f9d0149e8a5c68424bb691de15' (2023-08-21)
  → 'github:nixos/nixpkgs/b85ed9dcbf187b909ef7964774f8847d554fab3b' (2023-08-22)
```
2023-08-24 02:04:25 +00:00
49c5ddd9f3 nixpkgs: 2023-08-19 -> 2023-08-21
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/d680ded26da5cf104dd2735a51e88d2d8f487b4d' (2023-08-19)
  → 'github:nixos/nixpkgs/91a22f76cd1716f9d0149e8a5c68424bb691de15' (2023-08-21)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/f81e73cf9a4ef4b949b9225be3daa1e586c096da' (2023-08-15)
  → 'github:Mic92/sops-nix/1b7b3a32d65dbcd69c217d7735fdf0a6b2184f45' (2023-08-22)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/efeed708ece1a9f4ae0506ae4a4d7da264a74102' (2023-08-12)
  → 'github:NixOS/nixpkgs/5e63e8bbc46bc4fc22254da1edaf42fc7549c18a' (2023-08-20)
```
2023-08-23 13:40:45 +00:00
a43ccaac64 conky: display temperature 2023-08-23 13:38:11 +00:00
91c02aec9a sane-weather: enable cross compilation 2023-08-23 13:31:45 +00:00
681d3d5520 sane-weather: more diagnostics 2023-08-23 11:55:30 +00:00
f945dc42fa sane-weather: init
for now, all it does is print the current temperature; no caching
2023-08-23 11:14:13 +00:00
cc6f33b928 sxmo-utils: add missing curl, libxml2 deps 2023-08-23 06:18:24 +00:00
2f83e73139 sxmo: sway: default to tabbed workspaces 2023-08-22 10:03:07 +00:00
53ccb96234 sxmo: sway: theme "urgent" titlebars to match mpv colors 2023-08-22 10:00:13 +00:00
a0d6139e50 add todos around moby GPS 2023-08-22 08:53:55 +00:00
90abadf7c4 eg25-control: document typical jitter 2023-08-22 08:51:10 +00:00
7f1e959ece moby: gps: grant geoclue access to all users 2023-08-22 08:49:04 +00:00
794df4d762 moby: geoclue: restrict to just "colin" user 2023-08-22 07:20:31 +00:00
d6b262a28e moby: enable geoclue service 2023-08-22 07:15:14 +00:00
0cc518e523 todo.md: reflow 4-space tabs to 2-space 2023-08-22 06:41:26 +00:00
8780dff794 add lemonade, new-server-as-remote-builder to todo 2023-08-22 06:40:46 +00:00
0f881006e7 eg25-control: don't abort when AGPS download fails 2023-08-22 04:59:30 +00:00
5d349ce042 moby: init GPS during boot 2023-08-22 04:53:40 +00:00
940711878b eg25-control: make own package 2023-08-22 04:41:54 +00:00
75048efcf3 eg25_gps_init.py: allow CLI config of modem control points 2023-08-22 04:36:37 +00:00
8cc5199d9b FIXUP 2023-08-22 04:35:51 +00:00
3f60bacd38 eg25_gps_init: allow finer CLI control 2023-08-22 04:32:11 +00:00
8fb705dde4 eg25-gps-init: document the SIM requirement 2023-08-21 19:39:55 +00:00
79777cd4ae eg25-gps-init: improve docs 2023-08-21 11:14:16 +00:00
fabd1e3b64 eg25-gps-init: fixup docs 2023-08-21 10:42:27 +00:00
bcb6beef05 check in a script to initialize the eg25 gps
not part of the deployed system: has to be run manually
2023-08-21 10:33:39 +00:00
34336e4ade linux-megous: 6.4.0-rc7 -> 6.4.7
this is the version currently deployed by postmarketOS
2023-08-21 04:49:46 +00:00
a518e56cf1 feeds: leave note to where to find podcasts that have a lemmy community 2023-08-21 01:14:55 +00:00
6cc7655180 feeds: add Tom Scott's podcast 2023-08-21 01:13:19 +00:00
0a15aad6d7 sane-bt-search: rename "source" sort to "tracker" 2023-08-20 09:14:45 +00:00
1d8bee2856 sane-bt-search: add a flag to sort by tracker reputation 2023-08-20 09:14:19 +00:00
6894d5828b sane-bt-search: refactor: move filter logic off of Torrent class 2023-08-20 08:53:06 +00:00
35bc222552 sane-bt-search: allow showing only videos 2023-08-20 08:49:04 +00:00
16b5b6840f sane-bt-search: refactor: make filtering easier to extend 2023-08-20 08:45:10 +00:00
1a7837d740 flake: add a sync-lappy command 2023-08-20 07:46:55 +00:00
607bfbe452 fs: add /mnt/lappy-home 2023-08-20 06:26:20 +00:00
c2b85bd6b8 refactor: break out a helper in fs.nix for mounting remote home dirs 2023-08-20 06:20:28 +00:00
c3bc0ec645 fs: remove desko-root mount
i don't use it in practice
2023-08-20 06:11:17 +00:00
89b5e8145d lemmy: pict-rs: remove unused options 2023-08-20 05:01:24 +00:00
0edab7ed64 lemmy: port to new pict-rs and enable video 2023-08-20 05:00:35 +00:00
c8a3814f6a nixpkgs: 2023-08-18 -> 2023-08-19
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/8ecc900b2f695d74dea35a92f8a9f9b32c8ea33d' (2023-08-18)
  → 'github:nixos/nixpkgs/d680ded26da5cf104dd2735a51e88d2d8f487b4d' (2023-08-19)
```
2023-08-20 00:47:38 +00:00
9ddac508e2 sane-bt-search: port to argparse 2023-08-19 23:32:11 +00:00
3245f8f94c nixpkgs: 2023-08-17 -> 2023-08-18
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/42c25608aa2ad4e5d3716d8d63c606063513ba33' (2023-08-17)
  → 'github:nixos/nixpkgs/8ecc900b2f695d74dea35a92f8a9f9b32c8ea33d' (2023-08-18)
```
2023-08-19 11:30:18 +00:00
8be1f43c23 g4music: m4a support: acquire from upstream PR 2023-08-18 20:07:26 +00:00
e29e26605b nixpkgs: 2023-08-16 -> 2023-08-17
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/caac0eb6bdcad0b32cb2522e03e4002c8975c62e' (2023-08-16)
  → 'github:nixos/nixpkgs/42c25608aa2ad4e5d3716d8d63c606063513ba33' (2023-08-17)
```
2023-08-18 10:07:17 +00:00
7bd6c0c14d WIP: moby: launch ModemManager in debug mode
this lets me use mmcli --command=...
2023-08-18 10:05:32 +00:00
d7c912386f linux-megous: re-enable modem-power
it's likely i won't be using eg25-manager after all and will have to manually boot the modem, so may as well use Megi's driver for that
2023-08-18 04:08:32 +00:00
e7e86cae95 modemmanager: undo patching
once i insert a SIM, it's able to understand the modem...
2023-08-18 02:17:09 +00:00
b083ce87be eg25-manager: disable 2023-08-17 10:56:32 +00:00
17b90fc697 eg25-manager: configure without modemmanager support 2023-08-17 08:34:32 +00:00
4fc59fa2ac modemmanager: experimental patch to not fail the whole modem if there's no sim 2023-08-17 08:34:18 +00:00
e87cda2e55 g4music: add mp4 support 2023-08-17 01:51:25 +00:00
2c4d30b5ec postgresql: tune db parameters
fixes pleroma timeouts
2023-08-17 01:28:37 +00:00
d0af645af8 pleroma: add missing "prepare: :named" config 2023-08-17 01:28:33 +00:00
a1f79dc18a komikku: use unpatched upstream now that my fix is in a release 2023-08-17 00:01:15 +00:00
ff65a697a9 nixpatches: apply outstanding komikku, komga update PRs 2023-08-16 22:49:45 +00:00
ef881b1392 podcasts: subscribe to Useful Idiots 2023-08-16 22:03:40 +00:00
debea8fa5b podcasts: subscribe to Behind the Bastards 2023-08-16 21:58:51 +00:00
8a9acbaeea podcasts: subscribe to We're Not Wrong 2023-08-16 21:58:07 +00:00
8869ec7bca podcasts: subscribe to omegatau 2023-08-16 21:54:55 +00:00
dc0268736a g4music: remove (use upstream) 2023-08-16 21:25:25 +00:00
6f9c2a846e nixpkgs: 2023-08-15 -> 2023-08-16
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/8353344d3236d3fda429bb471c1ee008857d3b7c' (2023-08-15)
  → 'github:nixos/nixpkgs/caac0eb6bdcad0b32cb2522e03e4002c8975c62e' (2023-08-16)
```
2023-08-16 21:24:51 +00:00
3cb00840de nixpkgs: 2023-08-14 -> 2023-08-15
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/6e287913f7b1ef537c97aa301b67c34ea46b640f' (2023-08-14)
  → 'github:nixos/nixpkgs/8353344d3236d3fda429bb471c1ee008857d3b7c' (2023-08-15)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/32603de0dc988d60a7b80774dd7aed1083cd9629' (2023-08-13)
  → 'github:Mic92/sops-nix/f81e73cf9a4ef4b949b9225be3daa1e586c096da' (2023-08-15)
```
2023-08-16 11:31:04 +00:00
6a2603a4ea dev-machine: disable zeal (requires qtwebengine) 2023-08-16 11:29:43 +00:00
69efecb2ef postgresql: update 13 -> 15 2023-08-16 11:09:22 +00:00
056e6d358e moby: switch back to megi kernel (manjaro kernel has graphical glitches) 2023-08-16 10:59:58 +00:00
793baf0e0f cross: remove upstreamed tracker patches 2023-08-16 10:54:36 +00:00
721899258a cross: point playerctl patch to upstream PR 2023-08-16 10:54:07 +00:00
4f9d84cd82 cross: fix playerctl build 2023-08-16 10:34:13 +00:00
a462180d3c sane-stop-all-servo: add signald, pict-rs 2023-08-16 10:34:13 +00:00
58f2d87959 sane-stop-all-servo: add missing mautrix-signal and lemmy-ui services 2023-08-16 10:34:13 +00:00
a50b8e6373 moby: split the old linux-manjaro config into its own package & update it 2023-08-16 10:10:42 +00:00
4ec947d549 eg25-manager: set RestartSec to make the restart loops less painful 2023-08-16 09:09:13 +00:00
6751a74063 moby: kernel: better docs 2023-08-16 09:08:35 +00:00
6118a18200 gthumb: associate with gif and webp 2023-08-15 20:48:51 +00:00
d223d4be06 cross: try to fix webkitgtk build 2023-08-15 10:56:07 +00:00
ab7ec9bd74 cross: remove dead overrides for upstreamed packages 2023-08-15 10:55:18 +00:00
7b70b5ec86 linux-megous: build WITHOUT modem_power module, for better eg25-manager compatibility 2023-08-15 10:49:07 +00:00
db99043753 eg25-manager.service: remove modem_power module & point to the right UART 2023-08-15 10:46:18 +00:00
8f87e49606 cross: fix comment typos 2023-08-15 05:38:11 +00:00
5557107259 nixpkgs: 2023-08-13 -> 2023-08-14
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/100a1550b0e7a64b960c625b656f9229bdef5f87' (2023-08-13)
  → 'github:nixos/nixpkgs/6e287913f7b1ef537c97aa301b67c34ea46b640f' (2023-08-14)
```
2023-08-15 04:32:49 +00:00
1b5c870798 sane-scripts.sync-music: add to a package set (sane-scripts.sys-utils) 2023-08-15 01:47:45 +00:00
a5162651b7 zsh: re-enable lost keybindings like ctrl+r and ctrl+a 2023-08-15 01:47:12 +00:00
b9868512d6 switch TERMINAL from kitty -> alacritty 2023-08-15 01:46:57 +00:00
8432d9c9ed sway: be terminal agnostic 2023-08-15 01:46:40 +00:00
5d4f94f218 add alacritty program/config 2023-08-15 01:46:22 +00:00
7e9d5d99c7 g4music: obtain via nixpkgs PR 2023-08-14 20:19:22 +00:00
487e64b09b nixos/dconf patch: point to upstream PR 2023-08-14 20:13:19 +00:00
5e350b810f nixpkgs: 2023-08-10 -> 2023-08-13; sops-nix 2023-07-24 -> 2023-08-13
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/ce5e4a6ef2e59d89a971bc434ca8ca222b9c7f5e' (2023-08-10)
  → 'github:nixos/nixpkgs/100a1550b0e7a64b960c625b656f9229bdef5f87' (2023-08-13)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/c36df4fe4bf4bb87759b1891cab21e7a05219500' (2023-07-24)
  → 'github:Mic92/sops-nix/32603de0dc988d60a7b80774dd7aed1083cd9629' (2023-08-13)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/ce45b591975d070044ca24e3003c830d26fea1c8' (2023-07-22)
  → 'github:NixOS/nixpkgs/efeed708ece1a9f4ae0506ae4a4d7da264a74102' (2023-08-12)
```
2023-08-14 20:12:01 +00:00
5fb3a6be81 desko: disable jellyfin (just use mounted fs, avoid qtwebengine...) 2023-08-14 10:27:10 +00:00
dbec4b8f32 cross: expand buildInQemu to support a few more packages (e.g. g4music, but i didnt need it in the end) 2023-08-14 10:23:23 +00:00
f8b559bef1 g4music: docs on how to get it rendering correctly 2023-08-14 10:21:13 +00:00
7d9d0ce8b5 g4music: wrapGAppsHook -> wrapGAppsHook4 2023-08-14 10:20:54 +00:00
7857f123a4 new nix run '.#sync-moby' command to synchronize music onto my mobile phone 2023-08-14 08:20:06 +00:00
e3ba156fe1 fs: define /mnt/moby-home 2023-08-14 08:10:17 +00:00
c824751682 ~: don't symlink ~/Music/servo
it gets in the way for devices that have a full copy of their music
2023-08-14 08:10:06 +00:00
e5520437a5 sane-sync-music: init 2023-08-14 08:02:29 +00:00
c6211fe48f ship g4music 2023-08-14 06:17:22 +00:00
54d6c9008d g4music: init at 3.2 2023-08-14 06:13:22 +00:00
05e5edcce3 mpv: fix bug where GUI would be missing for some podcasts 2023-08-14 05:52:16 +00:00
3249baccfa mopidy: remove dead service code 2023-08-13 10:20:50 +00:00
274682cf85 mopidy: comment for how to disable spotify backend 2023-08-13 10:17:43 +00:00
31a700f6a7 mcg: support cross compilation 2023-08-13 09:39:04 +00:00
91a6fc32ef desktop: ship rhythmbox music player 2023-08-13 09:27:01 +00:00
135b87a091 mcg: init at 3.2.1 2023-08-13 09:24:17 +00:00
6b9484f611 cross: re-enable qt5 override. i dont actively use it but it is nice for testing 2023-08-13 07:49:29 +00:00
7a612b701d cross: emulateBuildMachine -> buildInQemu 2023-08-13 07:41:45 +00:00
c69fb690f1 cantata: fix to be in desktopGuiApps (because it needs qt) 2023-08-12 09:05:27 +00:00
1ef73dd69d mopidy: get spotify, jellyfin working 2023-08-12 09:00:33 +00:00
54afa1aec5 cross compiling: update status/notes 2023-08-12 08:26:18 +00:00
72c3c939e2 programs: ship cantata & mopidy for music playing (desktop) 2023-08-12 08:26:18 +00:00
67d8e89556 WIP: enable mopidy music server 2023-08-12 08:26:18 +00:00
07408813db python310Packages.keyring: re-enable cryptography dependency (it cross compiles now) 2023-08-12 08:03:16 +00:00
436760a592 python310Packages.keyring: fix cross compilation 2023-08-12 07:58:15 +00:00
5c758df032 gpodder-adaptive: fix cross compilation 2023-08-12 04:14:47 +00:00
d12a41bfa9 gpodder-adaptive: fix pname 2023-08-12 03:51:22 +00:00
8ec22b6320 mepo: fix autoPatchelfHook placement so it cross compiles 2023-08-12 02:44:14 +00:00
95d04467a8 cross: delete binfmt experiment (it will never work); comment out broken proot attempt 2023-08-11 23:28:37 +00:00
dd53de96fe cross: tune linuxMinimal 2023-08-11 23:25:26 +00:00
8089334ea9 cross: fix dconf-system-config 2023-08-11 23:06:25 +00:00
5bbb3678ed helix: support cross compilation 2023-08-11 23:01:46 +00:00
4e7ffe3140 cross compilation: simplify emulateBuilderQemu & use linux-megous as kernel when available 2023-08-11 22:27:35 +00:00
d2842484fd cross: do emulation with a smaller linux image (experimental) 2023-08-11 22:27:35 +00:00
a8932b5a72 WIP: try to cross-compile using proot instead of binfmt
but it doesn't seem to be emulating child processes...
2023-08-11 22:27:35 +00:00
a283d1ee21 linux-megous: simplify the package definition & build w/o debug info 2023-08-11 21:34:19 +00:00
d41d802d83 nixpkgs: 2023-08-09 -> 2023-08-10
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/e528fa15d5f740a25b5f536c33932db64cb10fc8' (2023-08-09)
  → 'github:nixos/nixpkgs/ce5e4a6ef2e59d89a971bc434ca8ca222b9c7f5e' (2023-08-10)
```
2023-08-11 21:32:53 +00:00
8a0efb3e40 servo: bump /tmp space to 32 GB 2023-08-11 07:10:25 +00:00
b013123669 moby: note for future self about a new display-manager failure case 2023-08-11 05:01:48 +00:00
264657d623 nixpkgs: 2023-08-08 -> 2023-08-09
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/41c7605718399dcfa53dd7083793b6ae3bc969ff' (2023-08-08)
  → 'github:nixos/nixpkgs/e528fa15d5f740a25b5f536c33932db64cb10fc8' (2023-08-09)
```
2023-08-10 21:20:56 +00:00
8ad4ee4341 bonsai: support cross compilation 2023-08-10 07:41:12 +00:00
664b21e5f1 enable eg25-manager (experimental) 2023-08-10 07:27:38 +00:00
163a7af328 fix pillow compilation 2023-08-10 05:51:01 +00:00
4adeae6d85 firefox-extensions.sponsorblock: support cross compilation 2023-08-09 23:22:32 +00:00
9168803008 seaborn (visidata dep): fix build 2023-08-09 21:08:32 +00:00
3f9c0d1b60 nixpkgs: 2023-08-07 -> 2023-08-08
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/5a8e9243812ba528000995b294292d3b5e120947' (2023-08-07)
  → 'github:nixos/nixpkgs/41c7605718399dcfa53dd7083793b6ae3bc969ff' (2023-08-08)
```
2023-08-09 07:58:03 +00:00
cc35317b54 bonsai: update PR to use PREFIX instead of DESTDIR 2023-08-09 03:16:55 +00:00
006070d08f cross: confirm that qt5 module emulation is actually necessary 2023-08-08 22:09:35 +00:00
19f6a98d31 nixpatches: note that i sent the mepo patch upstream 2023-08-08 07:03:45 +00:00
301abbe155 gtk{3,4}: acquire schema compilation patches via upstream PR 2023-08-08 01:53:48 +00:00
dab3a2d0a9 mate.engrampa: acquire cross compilation patch from upstream pr 2023-08-08 01:51:55 +00:00
3a00e93dc3 cross: fix mepo to cross compile again 2023-08-08 01:51:55 +00:00
4c4b0ce920 nixpkgs: 2023-08-04 -> 2023-08-07
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/18036c0be90f4e308ae3ebcab0e14aae0336fe42' (2023-08-04)
  → 'github:nixos/nixpkgs/5a8e9243812ba528000995b294292d3b5e120947' (2023-08-07)
```
2023-08-08 01:51:55 +00:00
b9259ff8b9 gtk{3,4}: tidy schema compilation patches 2023-08-08 01:51:55 +00:00
e2ed37196f browserpass-extension: emulate 2023-08-07 10:41:32 +00:00
b343d5d83a firefox-extensions.browserpass-extensions: enable module access via passthru 2023-08-07 10:26:29 +00:00
9bbff0d7a7 firefox-extensions.bypass-paywalls-clean: fix cross compilation by using the build-time zip 2023-08-07 10:26:24 +00:00
014fb5a633 gtk4 schema fix: include needed mesonEmulatorHook
this is probably needed for gtk3 too, only we get it for free when introspection is enabled
2023-08-07 08:30:56 +00:00
76d8921bdf eg25-manager: fix by importing the legacy libgpiod v1 as it appeared nixpkgs 1 wk ago 2023-08-07 08:29:06 +00:00
b7f23a032c eg25-manager: init at 0.4.6 2023-08-07 08:05:34 +00:00
68be1ba2a1 gtk{3,4}: compile schemas even on cross builds 2023-08-07 08:05:07 +00:00
5a6bb475c4 conky: support cross-compilation/wayland via nixpkgs patch stack 2023-08-07 07:33:01 +00:00
132e15cb9f sxmo-utils: switch runtime shell back to bash, but still use busybux during build
no need to patch it out of the build process
2023-08-07 04:29:38 +00:00
07c0878d11 sxmo-utils: force the scripts to run under busybox instead of default /bin/sh 2023-08-07 03:44:07 +00:00
b993479ada sxmo-utils: use busybox 2023-08-07 03:44:07 +00:00
8dc568d52e ship mate.engrampa as archive manager (after getting it to cross compile) 2023-08-07 03:43:37 +00:00
44ee7cd3db conky: build without emulation 2023-08-06 20:59:42 +00:00
2773cd8406 nixpkgs: 2023-08-02 -> 2023-08-04
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/66aedfd010204949cb225cf749be08cb13ce1813' (2023-08-02)
  → 'github:nixos/nixpkgs/18036c0be90f4e308ae3ebcab0e14aae0336fe42' (2023-08-04)
```
2023-08-06 09:59:46 +00:00
9bb26e0199 nixpatches: update xdg-utils cross patch 2023-08-06 09:42:25 +00:00
8d772074ba gupnp: acquire cross patch from upstream nixpkgs PR 2023-08-06 09:16:43 +00:00
18c6ad0663 cross: mepo: fix ld-linux path 2023-08-06 08:53:59 +00:00
24a91acd0a firefox-extensions: update hashes for sponsorblock, ublock-origin 2023-08-06 08:33:18 +00:00
bec5241326 qt5: build in emulator
qt5.qtbase does build, after an hour. qtdeclarative fails to complete even after 3 hours
2023-08-06 08:15:47 +00:00
2b5365d774 packages: only build nheko on desktop 2023-08-06 08:15:05 +00:00
e377a9f05b cross: emulateBuildMachine: bump RAM limit & add helper overrideAttrs fn 2023-08-06 08:13:46 +00:00
2f53e94cc9 mepo_1_1: remove package
i can just use normal `mepo` now.
2023-08-06 08:11:27 +00:00
75770cd34b cross compilation: get mepo to cross compile
in the end i don't even need to emulate zig... (yay)

the mepo_1_1 stuff isn't needed. i'll delete it next patch
2023-08-06 08:09:13 +00:00
a4860c3963 cross: allow makeWrapper in emulated builds 2023-08-06 01:51:55 +00:00
4b072ecbe5 cross: support browserpass-extension w/o emulation 2023-08-06 01:51:14 +00:00
3423f103fc firefox-extensions: tidy the wrapping and dont double-wrap 2023-08-06 01:50:40 +00:00
c3bb776149 cross: qt5.qtbase: build in qemu, not binfmt (holy cow, it actually builds this way) 2023-08-05 12:08:22 +00:00
d31aac4d19 tangram: build the blueprint compiler via qemu, not binfmt 2023-08-05 12:03:05 +00:00
378e72ceb7 cross: automatically convert nativeBuildInputs into their host equivalent 2023-08-05 11:53:14 +00:00
d86be97ced cross: fix emulateBuilder to use build bash in the vmRunCommand 2023-08-05 09:54:56 +00:00
44388b132a cross: fix enableParallelBuilding to work 2023-08-05 09:54:56 +00:00
cd6b112d33 build bonsai/hare/qbe without relying on binfmt emulation 2023-08-05 09:54:56 +00:00
8eb6be863a cross: koreader: build luajit from emulated stdenv, instead of grabbing it from the emulated packageset 2023-08-05 09:54:14 +00:00
105 changed files with 4848 additions and 1979 deletions

22
TODO.md
View File

@@ -1,7 +1,10 @@
## BUGS ## BUGS
- mpv UI is sometimes blank for audio/podcasts?
- i think it's when the audio file has no thumbnail?
- why i need to manually restart `wireguard-wg-ovpns` on servo periodically - why i need to manually restart `wireguard-wg-ovpns` on servo periodically
- else DNS fails - else DNS fails
- fix epiphany URL bar input on moby - fix epiphany URL bar input on moby
- sxmo: wvkbd: missing font for icons on the 3rd page
## REFACTORING: ## REFACTORING:
@@ -23,6 +26,10 @@
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617> - REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
- remove `libsForQt5.callPackage` broadly: <https://github.com/NixOS/nixpkgs/issues/180841> - remove `libsForQt5.callPackage` broadly: <https://github.com/NixOS/nixpkgs/issues/180841>
#### upstreaming to non-nixpkgs repos
- gtk: build schemas even on cross compilation: <https://github.com/NixOS/nixpkgs/pull/247844>
- sxmo: add new app entries
## IMPROVEMENTS: ## IMPROVEMENTS:
### security/resilience ### security/resilience
@@ -44,6 +51,13 @@
- integrate `nix check` into Gitea actions? - integrate `nix check` into Gitea actions?
### user experience ### user experience
- moby: sxmo: fix youtube scripts (package youtube-cli)
- moby: tune GPS
- run only geoclue, and not gpsd, to save power?
- tune QGPS setting in eg25-control, for less jitter?
- direct mepo to prefer gpsd, with fallback to geoclue, for better accuracy?
- configure geoclue to do some smoothing?
- manually do smoothing, as some layer between mepo and geoclue/gpsd?
- neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig) - neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig)
- Helix: make copy-to-system clipboard be the default - Helix: make copy-to-system clipboard be the default
- firefox/librewolf: persist history - firefox/librewolf: persist history
@@ -62,6 +76,12 @@
- email: fix so that local mail doesn't go to junk - email: fix so that local mail doesn't go to junk
- git sendmail flow adds the DKIM signatures, but gets delivered locally w/o having the sig checked, so goes into Junk - git sendmail flow adds the DKIM signatures, but gets delivered locally w/o having the sig checked, so goes into Junk
- could change junk filter from "no DKIM success" to explicit "DKIM failed" - could change junk filter from "no DKIM success" to explicit "DKIM failed"
- sxmo: don't put all deps on PATH
- maybe: use resholve to hard-code them
- this is the most "correct", but least patchable
- maybe: express each invocation as a function in sxmo_common.sh
- this will require some patching to handle `exec <foo>` style
- maybe: save original PATH and reset it before invoking user files
### perf ### perf
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled - add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
@@ -78,4 +98,6 @@
## NEW FEATURES: ## NEW FEATURES:
- migrate MAME cabinet to nix - migrate MAME cabinet to nix
- boot it from PXE from servo? - boot it from PXE from servo?
- deploy to new server, and use it as a remote builder
- enable IPv6 - enable IPv6
- package lemonade lemmy app: <https://linuxphoneapps.org/apps/ml.mdwalters.lemonade/>

18
flake.lock generated
View File

@@ -69,11 +69,11 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1690066826, "lastModified": 1693097136,
"narHash": "sha256-6L2qb+Zc0BFkh72OS9uuX637gniOjzU6qCDBpjB2LGY=", "narHash": "sha256-fBZSMdBaoZ0INFbyZ5s0DOF7zDNcLsLxgkwdDh3l9Pc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ce45b591975d070044ca24e3003c830d26fea1c8", "rev": "9117c4e9dc117a6cd0319cca40f2349ed333669d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -85,11 +85,11 @@
}, },
"nixpkgs-unpatched": { "nixpkgs-unpatched": {
"locked": { "locked": {
"lastModified": 1691006197, "lastModified": 1693663421,
"narHash": "sha256-DbtxVWPt+ZP5W0Usg7jAyTomIM//c3Jtfa59Ht7AV8s=", "narHash": "sha256-ImMIlWE/idjcZAfxKK8sQA7A1Gi/O58u5/CJA+mxvl8=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "66aedfd010204949cb225cf749be08cb13ce1813", "rev": "e56990880811a451abd32515698c712788be5720",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -116,11 +116,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1690199016, "lastModified": 1693404499,
"narHash": "sha256-yTLL72q6aqGmzHq+C3rDp3rIjno7EJZkFLof6Ika7cE=", "narHash": "sha256-cx/7yvM/AP+o/3wPJmA9W9F+WHemJk5t+Xcr+Qwkqhg=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "c36df4fe4bf4bb87759b1891cab21e7a05219500", "rev": "d9c5dc41c4b1f74c77f0dbffd0f3a4ebde447b7a",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -298,6 +298,26 @@
program = ''${deployScript "servo" "servo" "switch"}''; program = ''${deployScript "servo" "servo" "switch"}'';
}; };
sync-moby = {
# copy music from the current device to moby
# TODO: should i actually sync from /mnt/servo-media/Music instead of the local drive?
type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-moby" ''
sudo mount /mnt/moby-home
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music ~/Music /mnt/moby-home/Music
'');
};
sync-lappy = {
# copy music from servo to lappy
# can run this from any device that has ssh access to lappy
type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" ''
sudo mount /mnt/lappy-home
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music /mnt/servo-media/Music /mnt/lappy-home/Music
'');
};
check-nur = { check-nur = {
# `nix run '.#check-nur'` # `nix run '.#check-nur'`
# validates that my repo can be included in the Nix User Repository # validates that my repo can be included in the Nix User Repository
@@ -313,6 +333,19 @@
-I ../../ -I ../../
''); '');
}; };
check-host-configs = {
type = "app";
program = builtins.toString (pkgs.writeShellScript
"check-host-configs"
(builtins.concatStringsSep "\n" (builtins.map
(host: "nix build '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} -j1 $@ &")
[ "desko" "lappy" "servo" "moby" "rescue" ]
# not part of the `map`. wait for all builds to complete
++ [ "wait" ]
))
);
};
}; };
templates = { templates = {

View File

@@ -11,7 +11,7 @@
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip; sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
# sane.guest.enable = true; # sane.guest.enable = true;
sane.gui.sway.enable = true; sane.gui.sxmo.enable = true;
boot.loader.efi.canTouchEfiVariables = false; boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];

View File

@@ -3,7 +3,7 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.gui.sxmo = { sane.gui.sxmo = {
greeter = "sway"; greeter = "greetd-sway-gtkgreet";
settings = { settings = {
# XXX: make sure the user is part of the `input` group! # XXX: make sure the user is part of the `input` group!
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-id/usb-Wacom_Co._Ltd._Pen_and_multitouch_sensor-event-if00"; SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-id/usb-Wacom_Co._Ltd._Pen_and_multitouch_sensor-event-if00";
@@ -27,8 +27,11 @@
# - SXMO_SWAY_SCALE # - SXMO_SWAY_SCALE
# see <repo:mil/sxmo-utils:scripts/deviceprofiles> # see <repo:mil/sxmo-utils:scripts/deviceprofiles>
# SXMO_DEVICE_NAME = "pine64,pinephone-1.2"; # SXMO_DEVICE_NAME = "pine64,pinephone-1.2";
# if sxmo doesn't know the device, it can't decide whether to use one_button or three_button mode
# and so it just wouldn't handle any button inputs (sxmo_hook_inputhandler.sh not on path)
SXMO_DEVICE_NAME = "three_button_touchscreen";
}; };
package = pkgs.sxmo-utils.overrideAttrs (base: { package = pkgs.sxmo-utils-latest.overrideAttrs (base: {
postPatch = (base.postPatch or "") + '' postPatch = (base.postPatch or "") + ''
# after volume-button navigation mode, restore full keyboard functionality # after volume-button navigation mode, restore full keyboard functionality
cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons

View File

@@ -44,6 +44,7 @@
sane.programs.tuiApps.enableFor.user.colin = false; # visidata, others, don't compile well sane.programs.tuiApps.enableFor.user.colin = false; # visidata, others, don't compile well
# disabled for faster deploys # disabled for faster deploys
sane.programs.soundconverter.enableFor.user.colin = false; sane.programs.soundconverter.enableFor.user.colin = false;
sane.programs.eg25-control.enableFor.user.colin = true;
# sane.programs.firefox.mime.priority = 300; # prefer other browsers when possible # sane.programs.firefox.mime.priority = 300; # prefer other browsers when possible
# HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority` # HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority`
@@ -112,6 +113,15 @@
services.pipewire.environment.ALSA_CONFIG_UCM2 = ucm-env; services.pipewire.environment.ALSA_CONFIG_UCM2 = ucm-env;
services.pipewire-pulse.environment.ALSA_CONFIG_UCM2 = ucm-env; services.pipewire-pulse.environment.ALSA_CONFIG_UCM2 = ucm-env;
services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env; services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env;
# TODO: move elsewhere...
services.ModemManager.serviceConfig = {
# N.B.: the extra "" in ExecStart serves to force upstream ExecStart to be ignored
ExecStart = [ "" "${pkgs.modemmanager}/bin/ModemManager --debug" ];
# --debug sets DEBUG level logging: so reset
ExecStartPost = [ "${pkgs.modemmanager}/bin/mmcli --set-logging=INFO" ];
};
}; };
services.udev.extraRules = let services.udev.extraRules = let
@@ -127,37 +137,4 @@
''; '';
hardware.opengl.driSupport = true; hardware.opengl.driSupport = true;
services.xserver.displayManager.job.preStart = let
dmesg = "${pkgs.util-linux}/bin/dmesg";
grep = "${pkgs.gnugrep}/bin/grep";
modprobe = "${pkgs.kmod}/bin/modprobe";
in ''
# common boot failure:
# blank screen (no backlight even), with the following log:
# ```syslog
# sun8i-dw-hdmi 1ee0000.hdmi: Couldn't get the HDMI PHY
# ...
# sun4i-drm display-engine: Couldn't bind all pipelines components
# ...
# sun8i-dw-hdmi: probe of 1ee0000.hdmi failed with error -17
# ```
#
# in particular, that `probe ... failed` occurs *only* on failed boots
# (the other messages might sometimes occur even on successful runs?)
#
# reloading the sun8i hdmi driver usually gets the screen on, showing boot text.
# then restarting display-manager.service gets us to the login.
#
# NB: the above log is default level. though less specific, there's a `err` level message that also signals this:
# sun4i-drm display-engine: failed to bind 1ee0000.hdmi (ops sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -17
if (${dmesg} --kernel --level err --color=never --notime | ${grep} -q 'sun4i-drm display-engine: failed to bind 1ee0000.hdmi')
then
echo "reprobing sun8i_drm_hdmi"
# if a command here fails it errors the whole service, so prefer to log instead
${modprobe} -r sun8i_drm_hdmi || echo "failed to unload sun8i_drm_hdmi"
${modprobe} sun8i_drm_hdmi || echo "failed to load sub8i_drm_hdmi"
fi
'';
} }

View File

@@ -15,10 +15,28 @@
# #
# geoclue somehow fits in here as a geospatial provider that leverages GPS and also other sources like radio towers # geoclue somehow fits in here as a geospatial provider that leverages GPS and also other sources like radio towers
{ ... }: { lib, ... }:
{ {
# test gpsd with `gpspipe -w -n 10 2> /dev/null | grep -m 1 TPV | jq '.lat, .lon' | tr '\n' ' '`
# ^ should return <lat> <long>
services.gpsd.enable = true; services.gpsd.enable = true;
services.gpsd.devices = [ "/dev/ttyUSB1" ]; services.gpsd.devices = [ "/dev/ttyUSB1" ];
# TODO: enable eg25-manager, and bring online both the modem and GPS on boot # test geoclue2 by building `geoclue2-with-demo-agent`
# and running "${geoclue2-with-demo-agent}/libexec/geoclue-2/demos/where-am-i"
services.geoclue2.enable = true;
services.geoclue2.appConfig.where-am-i = {
# this is the default "agent", shipped by geoclue package: allow it to use location
isAllowed = true;
isSystem = false;
# XXX: setting users != [] might be causing `where-am-i` to time out
# users = [
# # restrict to only one set of users. empty array (default) means "allow any user to access geolocation".
# (builtins.toString config.users.users.colin.uid)
# ];
};
systemd.services.geoclue.after = lib.mkForce []; #< defaults to network-online, but not all my sources require network
sane.services.eg25-control.enable = true;
} }

View File

@@ -1,71 +1,56 @@
{ lib, pkgs, ... }: { pkgs, ... }:
let let
# use the last commit on the 5.18 branch (5.18.14) dmesg = "${pkgs.util-linux}/bin/dmesg";
# manjaro's changes between kernel patch versions tend to be minimal if any. grep = "${pkgs.gnugrep}/bin/grep";
manjaroBase = "https://gitlab.manjaro.org/manjaro-arm/packages/core/linux/-/raw/25bd828cd47b1c6e09fcbcf394a649b89d2876dd"; modprobe = "${pkgs.kmod}/bin/modprobe";
manjaroPatch = name: sha256: { ensureHWReady = ''
inherit name; # common boot failure:
patch = pkgs.fetchpatch { # blank screen (no backlight even), with the following log:
inherit name; # ```syslog
url = "${manjaroBase}/${name}?inline=false"; # sun8i-dw-hdmi 1ee0000.hdmi: Couldn't get the HDMI PHY
inherit sha256; # ...
}; # sun4i-drm display-engine: Couldn't bind all pipelines components
}; # ...
# sun8i-dw-hdmi: probe of 1ee0000.hdmi failed with error -17
# ```
#
# in particular, that `probe ... failed` occurs *only* on failed boots
# (the other messages might sometimes occur even on successful runs?)
#
# reloading the sun8i hdmi driver usually gets the screen on, showing boot text.
# then restarting display-manager.service gets us to the login.
#
# NB: the above log is default level. though less specific, there's a `err` level message that also signals this:
# sun4i-drm display-engine: failed to bind 1ee0000.hdmi (ops sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -17
# NB: this is the most common, but not the only, failure mode for `display-manager`.
# another error seems characterized by these dmesg logs, in which reprobing sun8i_drm_hdmi does not fix:
# ```syslog
# sun6i-mipi-dsi 1ca0000.dsi: Couldn't get the MIPI D-PHY
# sun4i-drm display-engine: Couldn't bind all pipelines components
# sun6i-mipi-dsi 1ca0000.dsi: Couldn't register our component
# ```
# the idea for patching off Manjaro's kernel comes from jakewaksbaum: if (${dmesg} --kernel --level err --color=never --notime | ${grep} -q 'sun4i-drm display-engine: failed to bind 1ee0000.hdmi')
# - https://git.sr.ht/~jakewaksbaum/pi/tree/af20aae5653545d6e67a459b59ee3e1ca8a680b0/item/kernel/default.nix then
# - he later abandoned this, i think because he's using the Pinephone Pro which received mainline support. echo "reprobing sun8i_drm_hdmi"
manjaroPatches = [ # if a command here fails it errors the whole service, so prefer to log instead
(manjaroPatch ${modprobe} -r sun8i_drm_hdmi || echo "failed to unload sun8i_drm_hdmi"
"1001-arm64-dts-allwinner-add-hdmi-sound-to-pine-devices.patch" ${modprobe} sun8i_drm_hdmi || echo "failed to load sub8i_drm_hdmi"
"sha256-DApd791A+AxB28Ven/MVAyuyVphdo8KQDx8O7oxVPnc=" fi
) '';
# these patches below are critical to enable wifi (RTL8723CS)
# - the alternative is a wholly forked kernel by megi/megous:
# - https://xnux.eu/howtos/build-pinephone-kernel.html#toc-how-to-build-megi-s-pinehpone-kernel
# - i don't know if these patches are based on megi's or original
(manjaroPatch
"2001-Bluetooth-Add-new-quirk-for-broken-local-ext-features.patch"
"sha256-CExhJuUWivegxPdnzKINEsKrMFx/m/1kOZFmlZ2SEOc="
)
(manjaroPatch
"2002-Bluetooth-btrtl-add-support-for-the-RTL8723CS.patch"
"sha256-dDdvOphTcP/Aog93HyH+L9m55laTgtjndPSE4/rnzUA="
)
(manjaroPatch
"2004-arm64-dts-allwinner-enable-bluetooth-pinetab-pinepho.patch"
"sha256-o43P3WzXyHK1PF+Kdter4asuyGAEKO6wf5ixcco2kCQ="
)
# XXX: this one has a Makefile, which hardcodes /sbin/depmod:
# - drivers/staging/rtl8723cs/Makefile
# - not sure if this is problematic?
(manjaroPatch
"2005-staging-add-rtl8723cs-driver.patch"
"sha256-6ywm3dQQ5JYl60CLKarxlSUukwi4QzqctCj3tVgzFbo="
)
];
in in
{ {
# use Megi's kernel:
# even with the Manjaro patches, stock 5.18 has a few issues on Pinephone:
# - no battery charging
# - phone rotation sensor is off by 90 degrees
# - ambient light sensor causes screen brightness to be shakey
# - phosh greeter may not appear after wake from sleep
boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-megous; boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-megous;
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-manjaro;
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_latest;
# alternatively, use nixos' kernel and add the stuff we want: # alternatively, apply patches directly to stock nixos kernel:
# # cross-compilation optimization:
# boot.kernelPackages =
# let p = (import nixpkgs { localSystem = "x86_64-linux"; });
# in p.pkgsCross.aarch64-multiplatform.linuxPackages_5_18;
# # non-cross:
# # boot.kernelPackages = pkgs.linuxPackages_5_18;
# boot.kernelPatches = manjaroPatches ++ [ # boot.kernelPatches = manjaroPatches ++ [
# (patchDefconfig kernelConfig) # (patchDefconfig kernelConfig)
# ]; # ];
# configure nixos to build a compressed kernel image, since it doesn't usually do that for aarch64 target.
# without this i run out of /boot space in < 10 generations
nixpkgs.hostPlatform.linux-kernel = { nixpkgs.hostPlatform.linux-kernel = {
# defaults: # defaults:
name = "aarch64-multiplatform"; name = "aarch64-multiplatform";
@@ -80,4 +65,7 @@ in
target = "Image.gz"; # <-- compress the kernel image target = "Image.gz"; # <-- compress the kernel image
# target = "zImage"; # <-- confuses other parts of nixos :-( # target = "zImage"; # <-- confuses other parts of nixos :-(
}; };
services.xserver.displayManager.job.preStart = ensureHWReady;
systemd.services.greetd.preStart = ensureHWReady;
} }

View File

@@ -167,7 +167,7 @@ in
WVKBD_LANDSCAPE_LAYERS = "landscape,special,emoji"; WVKBD_LANDSCAPE_LAYERS = "landscape,special,emoji";
WVKBD_LAYERS = "full,special,emoji"; WVKBD_LAYERS = "full,special,emoji";
}; };
package = pkgs.sxmo-utils.overrideAttrs (base: { package = pkgs.sxmo-utils-latest.overrideAttrs (base: {
postPatch = (base.postPatch or "") + '' postPatch = (base.postPatch or "") + ''
cat <<EOF >> ./configs/default_hooks/sxmo_hook_start.sh cat <<EOF >> ./configs/default_hooks/sxmo_hook_start.sh
# rotate UI based on physical display angle by default # rotate UI based on physical display angle by default

View File

@@ -2,6 +2,9 @@
{ {
sane.persist.root-on-tmpfs = true; sane.persist.root-on-tmpfs = true;
# increase /tmp space (defaults to 50% of RAM) for building large nix things.
# even the stock `nixpkgs.linux` consumes > 16 GB of tmp
fileSystems."/tmp".options = [ "size=32G" ];
fileSystems."/nix" = { fileSystems."/nix" = {
device = "/dev/disk/by-uuid/cc81cca0-3cc7-4d82-a00c-6243af3e7776"; device = "/dev/disk/by-uuid/cc81cca0-3cc7-4d82-a00c-6243af3e7776";

View File

@@ -7,7 +7,7 @@
./email ./email
./ejabberd.nix ./ejabberd.nix
./freshrss.nix ./freshrss.nix
./ftp ./export
./gitea.nix ./gitea.nix
./goaccess.nix ./goaccess.nix
./ipfs.nix ./ipfs.nix
@@ -18,7 +18,6 @@
./lemmy.nix ./lemmy.nix
./matrix ./matrix
./navidrome.nix ./navidrome.nix
./nfs.nix
./nixserve.nix ./nixserve.nix
./nginx.nix ./nginx.nix
./pict-rs.nix ./pict-rs.nix

View File

@@ -14,76 +14,105 @@
# #
# compliance tests: # compliance tests:
# - <https://compliance.conversations.im/server/uninsane.org/#xep0352> # - <https://compliance.conversations.im/server/uninsane.org/#xep0352>
#
# administration:
# - `sudo -u ejabberd ejabberdctl help`
#
# federation/support matrix:
# - avatars
# - nixnet.services + dino: works in MUCs but not DMs (as of 2023 H1)
# - movim.eu + dino: works in DMs, MUCs untested (as of 2023/08/29)
# - calls
# - local + dino: audio, video, works in DMs (as of 2023/08/29)
# - movim.eu + dino: audio, video, works in DMs, no matter which side initiates (as of 2023/08/30)
# - +native-cell-number@cheogram.com + dino: audio works in DMs, no matter which side initiates (as of 2023/09/01)
# - can receive calls even if sender isn't in my roster
# - this is presumably using JMP.chat's SIP servers, which then convert it to XMPP call
#
# bugs:
# - 2023/09/01: will randomly stop federating. `systemctl restart ejabberd` fixes, but takes 10 minutes.
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
# XXX: avatar support works in MUCs but not DMs let
# lib.mkIf false # TODO: this range could be larger, but right now that's costly because each element is its own UPnP forward
# TURN port range (inclusive)
turnPortLow = 49152;
turnPortHigh = 49167;
turnPortRange = lib.range turnPortLow turnPortHigh;
in
{ {
sane.persist.sys.plaintext = [ sane.persist.sys.plaintext = [
{ user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; } { user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; }
]; ];
sane.ports.ports."3478" = { sane.ports.ports = lib.mkMerge ([
{
"3478" = {
protocol = [ "tcp" "udp" ]; protocol = [ "tcp" "udp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-stun-turn"; description = "colin-xmpp-stun-turn";
}; };
sane.ports.ports."5222" = { "5222" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-client-to-server"; description = "colin-xmpp-client-to-server";
}; };
sane.ports.ports."5223" = { "5223" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpps-client-to-server"; # XMPP over TLS description = "colin-xmpps-client-to-server"; # XMPP over TLS
}; };
sane.ports.ports."5269" = { "5269" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-server-to-server"; description = "colin-xmpp-server-to-server";
}; };
sane.ports.ports."5270" = { "5270" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpps-server-to-server"; # XMPP over TLS description = "colin-xmpps-server-to-server"; # XMPP over TLS
}; };
sane.ports.ports."5280" = { "5280" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-bosh"; description = "colin-xmpp-bosh";
}; };
sane.ports.ports."5281" = { "5281" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-bosh-https"; description = "colin-xmpp-bosh-https";
}; };
sane.ports.ports."5349" = { "5349" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-stun-turn-over-tls"; description = "colin-xmpp-stun-turn-over-tls";
}; };
sane.ports.ports."5443" = { "5443" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-xmpp-web-services"; # file uploads, websockets, admin description = "colin-xmpp-web-services"; # file uploads, websockets, admin
}; };
}
# TODO: forward these TURN ports! ] ++ (builtins.map
networking.firewall.allowedTCPPortRanges = [{ (port: {
from = 49152; # TURN "${builtins.toString port}" = let
to = 49408; count = port - turnPortLow + 1;
}]; numPorts = turnPortHigh - turnPortLow + 1;
networking.firewall.allowedUDPPortRanges = [{ in {
from = 49152; # TURN protocol = [ "tcp" "udp" ];
to = 49408; visibleTo.lan = true;
}]; visibleTo.wan = true;
description = "colin-xmpp-turn-${builtins.toString count}-of-${builtins.toString numPorts}";
};
})
turnPortRange
));
# provide access to certs # provide access to certs
# TODO: this should just be `acme`. then we also add nginx to the `acme` group. # TODO: this should just be `acme`. then we also add nginx to the `acme` group.
@@ -272,8 +301,8 @@
module: ejabberd_stun module: ejabberd_stun
transport: tcp transport: tcp
use_turn: true use_turn: true
turn_min_port: 49152 turn_min_port: ${builtins.toString turnPortLow}
turn_max_port: 65535 turn_max_port: ${builtins.toString turnPortHigh}
turn_ipv4_address: %ANATIVE% turn_ipv4_address: %ANATIVE%
- -
# STUN+TURN UDP # STUN+TURN UDP
@@ -281,8 +310,8 @@
module: ejabberd_stun module: ejabberd_stun
transport: udp transport: udp
use_turn: true use_turn: true
turn_min_port: 49152 turn_min_port: ${builtins.toString turnPortLow}
turn_max_port: 65535 turn_max_port: ${builtins.toString turnPortHigh}
turn_ipv4_address: %ANATIVE% turn_ipv4_address: %ANATIVE%
- -
# STUN+TURN TLS over TCP # STUN+TURN TLS over TCP
@@ -292,8 +321,8 @@
tls: true tls: true
certfile: /var/lib/acme/uninsane.org/full.pem certfile: /var/lib/acme/uninsane.org/full.pem
use_turn: true use_turn: true
turn_min_port: 49152 turn_min_port: ${builtins.toString turnPortLow}
turn_max_port: 65535 turn_max_port: ${builtins.toString turnPortHigh}
turn_ipv4_address: %ANATIVE% turn_ipv4_address: %ANATIVE%
# TODO: enable mod_fail2ban # TODO: enable mod_fail2ban

View File

@@ -0,0 +1,53 @@
{ config, ... }:
{
imports = [
./nfs.nix
./sftpgo.nix
];
users.groups.export = {};
fileSystems."/var/export/media" = {
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
device = "/var/lib/uninsane/media";
options = [ "rbind" ];
};
# fileSystems."/var/export/playground" = {
# device = config.fileSystems."/mnt/persist/ext".device;
# fsType = "btrfs";
# options = [
# "subvol=export-playground"
# "compress=zstd"
# "defaults"
# ];
# };
# N.B.: the backing directory should be manually created here **as a btrfs subvolume** and with a quota.
# - `sudo btrfs subvolume create /mnt/persist/ext/persist/var/export/playground`
# - `sudo btrfs quota enable /mnt/persist/ext/persist/var/export/playground`
# - `sudo btrfs quota rescan -sw /mnt/persist/ext/persist/var/export/playground`
# to adjust the limits (which apply at the block layer, i.e. post-compression):
# - `sudo btrfs qgroup limit 20G /mnt/persist/ext/persist/var/export/playground`
# to query the quota/status:
# - `sudo btrfs qgroup show -re /var/export/playground`
sane.persist.sys.ext = [
{ user = "root"; group = "export"; mode = "0775"; path = "/var/export/playground"; }
];
sane.fs."/var/export/README.md" = {
wantedBy = [ "nfs.service" "sftpgo.service" ];
file.text = ''
- media/ read-only: Videos, Music, Books, etc
- playground/ read-write: use it to share files with other users of this server
'';
};
sane.fs."/var/export/playground/README.md" = {
wantedBy = [ "nfs.service" "sftpgo.service" ];
file.text = ''
this directory is intentionally read+write by anyone with access (i.e. on the LAN).
- share files
- write poetry
- be a friendly troll
'';
};
}

View File

@@ -0,0 +1,110 @@
# docs:
# - <https://nixos.wiki/wiki/NFS>
# - <https://wiki.gentoo.org/wiki/Nfs-utils>
# system files:
# - /etc/exports
# system services:
# - nfs-server.service
# - nfs-idmapd.service
# - nfs-mountd.service
# - nfsdcld.service
# - rpc-statd.service
# - rpcbind.service
#
# TODO: force files to be 755, or 750.
# - could maybe be done with some mount option?
{ config, lib, ... }:
{
services.nfs.server.enable = true;
# see which ports NFS uses with:
# - `rpcinfo -p`
sane.ports.ports."111" = {
protocol = [ "tcp" "udp" ];
visibleTo.lan = true;
description = "NFS server portmapper";
};
sane.ports.ports."2049" = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "NFS server";
};
sane.ports.ports."4000" = {
protocol = [ "udp" ];
visibleTo.lan = true;
description = "NFS server status daemon";
};
sane.ports.ports."4001" = {
protocol = [ "tcp" "udp" ];
visibleTo.lan = true;
description = "NFS server lock daemon";
};
sane.ports.ports."4002" = {
protocol = [ "tcp" "udp" ];
visibleTo.lan = true;
description = "NFS server mount daemon";
};
# NFS4 allows these to float, but NFS3 mandates specific ports, so fix them for backwards compat.
services.nfs.server.lockdPort = 4001;
services.nfs.server.mountdPort = 4002;
services.nfs.server.statdPort = 4000;
# format:
# fspoint visibility(options)
# options:
# - see: <https://wiki.gentoo.org/wiki/Nfs-utils#Exports>
# - see [man 5 exports](https://linux.die.net/man/5/exports)
# - insecure: require clients use src port > 1024
# - rw, ro (default)
# - async, sync (default)
# - no_subtree_check (default), subtree_check: verify not just that files requested by the client live
# in the expected fs, but also that they live under whatever subdirectory of that fs is exported.
# - no_root_squash, root_squash (default): map requests from uid 0 to user `nobody`.
# - crossmnt: reveal filesystems that are mounted under this endpoint
# - fsid: must be zero for the root export
# - fsid=root is alias for fsid=0
# - mountpoint[=/path]: only export the directory if it's a mountpoint. used to avoid exporting failed mounts.
# - all_squash: rewrite all client requests such that they come from anonuid/anongid
# - any files a user creates are owned by local anonuid/anongid.
# - users can read any local file which anonuid/anongid would be able to read.
# - users can't chown to/away from anonuid/anongid.
# - users can chmod files they own, to anything (making them unreadable to non-`nfsuser` export users, like FTP).
# - `stat` remains unchanged, returning the real UIDs/GIDs to the client.
# - thus programs which check `uid` or `gid` before trying an operation may incorrectly conclude they can't perform some op.
#
# 10.0.0.0/8 to export both to LAN (readonly, unencrypted) and wg vpn (read-write, encrypted)
services.nfs.server.exports =
let
fmtExport = { export, baseOpts, extraLanOpts ? [], extraVpnOpts ? [] }:
let
always = [ "subtree_check" ];
lanOpts = always ++ baseOpts ++ extraLanOpts;
vpnOpts = always ++ baseOpts ++ extraVpnOpts;
in "${export} 10.78.79.0/22(${lib.concatStringsSep "," lanOpts}) 10.0.10.0/24(${lib.concatStringsSep "," vpnOpts})";
in lib.concatStringsSep "\n" [
(fmtExport {
export = "/var/export";
baseOpts = [ "crossmnt" "fsid=root" ];
extraLanOpts = [ "ro" ];
extraVpnOpts = [ "rw" "no_root_squash" ];
})
(fmtExport {
export = "/var/export/playground";
baseOpts = [
"mountpoint"
"all_squash"
"rw"
"anonuid=${builtins.toString config.users.users.nfsuser.uid}"
"anongid=${builtins.toString config.users.groups.export.gid}"
];
})
];
users.users.nfsuser = {
description = "virtual user for anonymous NFS operations";
group = "export";
isSystemUser = true;
};
}

View File

@@ -0,0 +1,179 @@
# docs:
# - <https://github.com/drakkan/sftpgo>
# - config options: <https://github.com/drakkan/sftpgo/blob/main/docs/full-configuration.md>
# - config defaults: <https://github.com/drakkan/sftpgo/blob/main/sftpgo.json>
# - nixos options: <repo:nixos/nixpkgs:nixos/modules/services/web-apps/sftpgo.nix>
# - nixos example: <repo:nixos/nixpkgs:nixos/tests/sftpgo.nix>
#
# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients.
#
# TODO: change umask so sftpgo-created files default to 644.
# - it does indeed appear that the 600 is not something sftpgo is explicitly doing.
{ config, lib, pkgs, sane-lib, ... }:
let
# user permissions:
# - see <repo:drakkan/sftpgo:internal/dataprovider/user.go>
# - "*" = grant all permissions
# - read-only perms:
# - "list" = list files and directories
# - "download"
# - rw perms:
# - "upload"
# - "overwrite" = allow uploads to replace existing files
# - "delete" = delete files and directories
# - "delete_files"
# - "delete_dirs"
# - "rename" = rename files and directories
# - "rename_files"
# - "rename_dirs"
# - "create_dirs"
# - "create_symlinks"
# - "chmod"
# - "chown"
# - "chtimes" = change atime/mtime (access and modification times)
#
# home_dir:
# - it seems (empirically) that a user can't cd above their home directory.
# though i don't have a reference for that in the docs.
authResponseSuccess = {
status = 1;
username = "anonymous";
expiration_date = 0;
home_dir = "/var/export";
# uid/gid 0 means to inherit sftpgo uid.
# - i.e. users can't read files which Linux user `sftpgo` can't read
# - uploaded files belong to Linux user `sftpgo`
# other uid/gid values aren't possible for localfs backend, unless i let sftpgo use `sudo`.
uid = 0;
gid = 0;
# uid = 65534;
# gid = 65534;
max_sessions = 0;
# quota_*: 0 means to not use SFTP's quota system
quota_size = 0;
quota_files = 0;
permissions = {
"/" = [ "list" "download" ];
"/playground" = [
# read-only:
"list"
"download"
# write:
"upload"
"overwrite"
"delete"
"rename"
"create_dirs"
"create_symlinks"
# intentionally omitted:
# "chmod"
# "chown"
# "chtimes"
];
};
upload_bandwidth = 0;
download_bandwidth = 0;
filters = {
allowed_ip = [];
denied_ip = [];
};
public_keys = [];
# other fields:
# ? groups
# ? virtual_folders
};
authResponseFail = {
username = "";
};
authSuccessJson = pkgs.writeText "sftp-auth-success.json" (builtins.toJSON authResponseSuccess);
authFailJson = pkgs.writeText "sftp-auth-fail.json" (builtins.toJSON authResponseFail);
unwrappedAuthProgram = pkgs.static-nix-shell.mkBash {
pname = "sftpgo_external_auth_hook";
src = ./.;
pkgs = [ "coreutils" ];
};
authProgram = pkgs.writeShellScript "sftpgo-auth-hook" ''
${unwrappedAuthProgram}/bin/sftpgo_external_auth_hook ${authFailJson} ${authSuccessJson}
'';
in
{
# Client initiates a FTP "control connection" on port 21.
# - this handles the client -> server commands, and the server -> client status, but not the actual data
# - file data, directory listings, etc need to be transferred on an ephemeral "data port".
# - 50000-50100 is a common port range for this.
sane.ports.ports = {
"21" = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "colin-FTP server";
};
} // (sane-lib.mapToAttrs
(port: {
name = builtins.toString port;
value = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "colin-FTP server data port range";
};
})
(lib.range 50000 50100)
);
services.sftpgo = {
enable = true;
group = "export";
settings = {
ftpd = {
bindings = [
{
# binding this means any wireguard client can connect
address = "10.0.10.5";
port = 21;
debug = true;
}
{
# binding this means any LAN client can connect
address = "10.78.79.51";
port = 21;
debug = true;
}
];
# active mode is susceptible to "bounce attacks", without much benefit over passive mode
disable_active_mode = true;
hash_support = true;
passive_port_range = {
start = 50000;
end = 50100;
};
banner = ''
Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host.
Username: "anonymous"
Password: "anonymous"
CONFIGURE YOUR CLIENT FOR "PASSIVE" mode, e.g. `ftp --passive uninsane.org`
Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :)
'';
};
data_provider = {
driver = "memory";
external_auth_hook = "${authProgram}";
# track_quota:
# - 0: disable quota tracking
# - 1: quota is updated on every upload/delete, even if user has no quota restriction
# - 2: quota is updated on every upload/delete, but only if user/folder has a quota restriction (default, i think)
# track_quota = 2;
};
};
};
users.users.sftpgo.extraGroups = [ "export" ];
systemd.services.sftpgo.serviceConfig = {
ReadOnlyPaths = [ "/var/export" ];
ReadWritePaths = [ "/var/export/playground" ];
};
}

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p coreutils
# vim: set filetype=bash :
#
# available environment variables:
# - SFTPGO_AUTHD_USERNAME
# - SFTPGO_AUTHD_USER
# - SFTPGO_AUTHD_IP
# - SFTPGO_AUTHD_PROTOCOL = { "DAV", "FTP", "HTTP", "SSH" }
# - SFTPGO_AUTHD_PASSWORD
# - SFTPGO_AUTHD_PUBLIC_KEY
# - SFTPGO_AUTHD_KEYBOARD_INTERACTIVE
# - SFTPGO_AUTHD_TLS_CERT
#
#
# call with <script_name> /path/to/fail/response.json /path/to/success/response.json
if [ "$SFTPGO_AUTHD_USERNAME" = "anonymous" ]; then
cat "$2"
else
cat "$1"
fi

View File

@@ -1,70 +0,0 @@
# docs:
# - <https://github.com/drakkan/sftpgo>
# - config options: <https://github.com/drakkan/sftpgo/blob/main/docs/full-configuration.md>
# - config defaults: <https://github.com/drakkan/sftpgo/blob/main/sftpgo.json>
# - nixos options: <repo:nixos/nixpkgs:nixos/modules/services/web-apps/sftpgo.nix>
#
# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients.
{ lib, pkgs, sane-lib, ... }:
let
authProgram = pkgs.static-nix-shell.mkBash {
pname = "sftpgo_external_auth_hook";
src = ./.;
};
in
{
# Client initiates a FTP "control connection" on port 21.
# - this handles the client -> server commands, and the server -> client status, but not the actual data
# - file data, directory listings, etc need to be transferred on an ephemeral "data port".
# - 50000-50100 is a common port range for this.
sane.ports.ports = {
"21" = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "colin-FTP server";
};
} // (sane-lib.mapToAttrs
(port: {
name = builtins.toString port;
value = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "colin-FTP server data port range";
};
})
(lib.range 50000 50100)
);
services.sftpgo = {
enable = true;
settings = {
ftpd = {
bindings = [{
address = "10.0.10.5";
port = 21;
debug = true;
}];
# active mode is susceptible to "bounce attacks", without much benefit over passive mode
disable_active_mode = true;
hash_support = true;
passive_port_range = {
start = 50000;
end = 50100;
};
banner = ''
Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host.
Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :)
'';
};
data_provider = {
driver = "memory";
external_auth_hook = "${authProgram}/bin/sftpgo_external_auth_hook";
};
};
};
}

View File

@@ -1,55 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash
# vim: set filetype=bash :
#
# available environment variables:
# - SFTPGO_AUTHD_USERNAME
# - SFTPGO_AUTHD_USER
# - SFTPGO_AUTHD_IP
# - SFTPGO_AUTHD_PROTOCOL = { "DAV", "FTP", "HTTP", "SSH" }
# - SFTPGO_AUTHD_PASSWORD
# - SFTPGO_AUTHD_PUBLIC_KEY
# - SFTPGO_AUTHD_KEYBOARD_INTERACTIVE
# - SFTPGO_AUTHD_TLS_CERT
#
# user permissions:
# - see <repo:drakkan/sftpgo:internal/dataprovider/user.go>
# - "*" = grant all permissions
# - read-only perms:
# - "list" = list files and directories
# - "download"
# - rw perms:
# - "upload"
# - "overwrite" = allow uploads to replace existing files
# - "delete" = delete files and directories
# - "delete_files"
# - "delete_dirs"
# - "rename" = rename files and directories
# - "rename_files"
# - "rename_dirs"
# - "create_dirs"
# - "create_symlinks"
# - "chmod"
# - "chown"
# - "chtimes" = change atime/mtime (access and modification times)
#
# home_dir:
# - it seems (empirically) that a user can't cd above their home directory.
# though i don't have a reference for that in the docs.
# TODO: don't reuse /var/nfs/export here. formalize this some other way.
if [ "$SFTPGO_AUTHD_USERNAME" = "anonymous" ]; then
echo '{'
echo ' "status":1,'
echo ' "username":"anonymous","expiration_date":0,'
echo ' "home_dir":"/var/nfs/export","uid":65534,"gid":65534,"max_sessions":0,"quota_size":0,"quota_files":100000,'
echo ' "permissions":{'
echo ' "/":["list", "download"]'
echo ' },'
echo ' "upload_bandwidth":0,"download_bandwidth":0,'
echo ' "filters":{"allowed_ip":[],"denied_ip":[]},"public_keys":[]'
echo '}'
else
echo '{"username":""}'
fi

View File

@@ -3,13 +3,23 @@
# - <repo:LemmyNet/lemmy:docker/nginx.conf> # - <repo:LemmyNet/lemmy:docker/nginx.conf>
# - <repo:LemmyNet/lemmy-ansible:templates/nginx.conf> # - <repo:LemmyNet/lemmy-ansible:templates/nginx.conf>
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
inherit (builtins) toString; inherit (builtins) toString;
inherit (lib) mkForce; inherit (lib) mkForce;
uiPort = 1234; # default ui port is 1234 uiPort = 1234; # default ui port is 1234
backendPort = 8536; # default backend port is 8536 backendPort = 8536; # default backend port is 8536
# - i guess the "backend" port is used for federation? #^ i guess the "backend" port is used for federation?
pict-rs = pkgs.pict-rs.overrideAttrs (upstream: {
# as of v 0.4.2, all non-GIF video is forcibly transcoded.
# that breaks lemmy, because of the request latency.
# and it eats up hella CPU.
# pict-rs is iffy around video altogether: mp4 seems the best supported.
postPatch = (upstream.postPatch or "") + ''
substituteInPlace src/validate.rs \
--replace 'if transcode_options.needs_reencode() {' 'if false {'
'';
});
in { in {
services.lemmy = { services.lemmy = {
enable = true; enable = true;
@@ -56,4 +66,20 @@ in {
}; };
sane.dns.zones."uninsane.org".inet.CNAME."lemmy" = "native"; sane.dns.zones."uninsane.org".inet.CNAME."lemmy" = "native";
#v DO NOT REMOVE: defaults to 0.3, instead of latest, so always need to explicitly set this.
services.pict-rs.package = pict-rs;
# pict-rs configuration is applied in this order:
# - via toml
# - via env vars (overrides everything above)
# - via CLI flags (overrides everything above)
# some of the CLI flags have defaults, making it the only actual way to configure certain things even when docs claim otherwise.
# CLI args: <https://git.asonix.dog/asonix/pict-rs#user-content-running>
systemd.services.pict-rs.serviceConfig.ExecStart = lib.mkForce (lib.concatStringsSep " " [
"${lib.getBin pict-rs}/bin/pict-rs run"
"--media-max-frame-count" (builtins.toString (30*60*60))
"--media-process-timeout 120"
"--media-enable-full-video true" # allow audio
]);
} }

View File

@@ -1,67 +0,0 @@
# docs:
# - <https://nixos.wiki/wiki/NFS>
# - <https://wiki.gentoo.org/wiki/Nfs-utils>
{ ... }:
{
services.nfs.server.enable = true;
# see which ports NFS uses with:
# - `rpcinfo -p`
sane.ports.ports."111" = {
protocol = [ "tcp" "udp" ];
visibleTo.lan = true;
description = "NFS server portmapper";
};
sane.ports.ports."2049" = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "NFS server";
};
sane.ports.ports."4000" = {
protocol = [ "udp" ];
visibleTo.lan = true;
description = "NFS server status daemon";
};
sane.ports.ports."4001" = {
protocol = [ "tcp" "udp" ];
visibleTo.lan = true;
description = "NFS server lock daemon";
};
sane.ports.ports."4002" = {
protocol = [ "tcp" "udp" ];
visibleTo.lan = true;
description = "NFS server mount daemon";
};
# NFS4 allows these to float, but NFS3 mandates specific ports, so fix them for backwards compat.
services.nfs.server.lockdPort = 4001;
services.nfs.server.mountdPort = 4002;
services.nfs.server.statdPort = 4000;
# format:
# fspoint visibility(options)
# options:
# - see: <https://wiki.gentoo.org/wiki/Nfs-utils#Exports>
# - see [man 5 exports](https://linux.die.net/man/5/exports)
# - insecure: require clients use src port > 1024
# - rw, ro (default)
# - async, sync (default)
# - no_subtree_check (default), subtree_check: verify not just that files requested by the client live
# in the expected fs, but also that they live under whatever subdirectory of that fs is exported.
# - no_root_squash, root_squash (default): map requests from uid 0 to user `nobody`.
# - crossmnt: reveal filesystems that are mounted under this endpoint
# - fsid: must be zero for the root export
# - mountpoint[=/path]: only export the directory if it's a mountpoint. used to avoid exporting failed mounts.
#
# 10.0.0.0/8 to export (readonly) both to LAN (unencrypted) and wg vpn (encrypted)
services.nfs.server.exports = ''
/var/nfs/export 10.78.79.0/22(ro,crossmnt,fsid=0,subtree_check) 10.0.10.0/24(rw,no_root_squash,crossmnt,fsid=0,subtree_check)
'';
fileSystems."/var/nfs/export/media" = {
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
device = "/var/lib/uninsane/media";
options = [ "rbind" ];
};
}

View File

@@ -63,6 +63,7 @@ in
database: "pleroma", database: "pleroma",
hostname: "localhost", hostname: "localhost",
pool_size: 10, pool_size: 10,
prepare: :named,
parameters: [ parameters: [
plan_cache_mode: "force_custom_plan" plan_cache_mode: "force_custom_plan"
] ]

View File

@@ -1,12 +1,39 @@
{ ... }: { pkgs, ... }:
let
GiB = n: MiB 1024*n;
MiB = n: KiB 1024*n;
KiB = n: 1024*n;
in
{ {
sane.persist.sys.plaintext = [ sane.persist.sys.plaintext = [
# TODO: mode? # TODO: mode?
{ user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; } { user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; }
]; ];
services.postgresql.enable = true; services.postgresql.enable = true;
# services.postgresql.dataDir = "/opt/postgresql/13";
# HOW TO UPDATE:
# postgres version updates are manual and require intervention.
# - `sane-stop-all-servo`
# - `systemctl start postgresql`
# - as `sudo su postgres`:
# - `cd /var/log/postgresql`
# - `pg_dumpall > state.sql`
# - `echo placeholder > <new_version>` # to prevent state from being created earlier than we want
# - then, atomically:
# - update the `services.postgresql.package` here
# - `dataDir` is atomically updated to match package; don't touch
# - `nixos-rebuild --flake . switch ; sane-stop-all-servo`
# - `sudo rm -rf /var/lib/postgresql/<new_version>`
# - `systemctl start postgresql`
# - as `sudo su postgres`:
# - `cd /var/lib/postgreql`
# - `psql -f state.sql`
# - restart dependent services (maybe test one at a time)
services.postgresql.package = pkgs.postgresql_15;
# XXX colin: for a proper deploy, we'd want to include something for Pleroma here too. # XXX colin: for a proper deploy, we'd want to include something for Pleroma here too.
# services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' # services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
# CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>'; # CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>';
@@ -17,10 +44,33 @@
# LC_CTYPE = "C"; # LC_CTYPE = "C";
# ''; # '';
# TODO: perf tuning # perf tuning
# - for recommended values see: <https://pgtune.leopard.in.ua/> # - for recommended values see: <https://pgtune.leopard.in.ua/>
# - for official docs (sparse), see: <https://www.postgresql.org/docs/11/config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE> # - for official docs (sparse), see: <https://www.postgresql.org/docs/11/config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE>
# services.postgresql.settings = { ... } services.postgresql.settings = {
# DB Version: 15
# OS Type: linux
# DB Type: web
# Total Memory (RAM): 32 GB
# CPUs num: 12
# Data Storage: ssd
max_connections = 200;
shared_buffers = "8GB";
effective_cache_size = "24GB";
maintenance_work_mem = "2GB";
checkpoint_completion_target = 0.9;
wal_buffers = "16MB";
default_statistics_target = 100;
random_page_cost = 1.1;
effective_io_concurrency = 200;
work_mem = "10485kB";
min_wal_size = "1GB";
max_wal_size = "4GB";
max_worker_processes = 12;
max_parallel_workers_per_gather = 4;
max_parallel_workers = 12;
max_parallel_maintenance_workers = 4;
};
# daily backups to /var/backup # daily backups to /var/backup
services.postgresqlBackup.enable = true; services.postgresqlBackup.enable = true;

View File

@@ -1,4 +1,5 @@
# where to find good stuff? # where to find good stuff?
# - podcasts w/ a community: <https://lemmyverse.net/communities?query=podcast>
# - podcast rec thread: <https://lemmy.ml/post/1565858> # - podcast rec thread: <https://lemmy.ml/post/1565858>
# #
# candidates: # candidates:
@@ -67,7 +68,12 @@ let
(fromDb "craphound.com" // pol) (fromDb "craphound.com" // pol)
## Maggie Killjoy -- referenced by Cory Doctorow ## Maggie Killjoy -- referenced by Cory Doctorow
(fromDb "omny.fm/shows/cool-people-who-did-cool-stuff" // pol) (fromDb "omny.fm/shows/cool-people-who-did-cool-stuff" // pol)
## also Maggie Killjoy
(fromDb "feeds.megaphone.fm/behindthebastards" // pol)
## Jennifer Briney
(fromDb "congressionaldish.libsyn.com" // pol) (fromDb "congressionaldish.libsyn.com" // pol)
(fromDb "werenotwrong.fireside.fm" // pol)
(fromDb "usefulidiots.substack.com" // pol)
# (mkPod "https://podcasts.la.utexas.edu/this-is-democracy/feed/podcast/" // pol // weekly) # (mkPod "https://podcasts.la.utexas.edu/this-is-democracy/feed/podcast/" // pol // weekly)
## Civboot -- https://anchor.fm/civboot ## Civboot -- https://anchor.fm/civboot
(fromDb "anchor.fm/s/34c7232c/podcast/rss" // tech) (fromDb "anchor.fm/s/34c7232c/podcast/rss" // tech)
@@ -125,6 +131,10 @@ let
(fromDb "feeds.simplecast.com/82FI35Px" // pol) (fromDb "feeds.simplecast.com/82FI35Px" // pol)
## Wireshark Podcast o_0 ## Wireshark Podcast o_0
(fromDb "sharkbytes.transistor.fm" // tech) (fromDb "sharkbytes.transistor.fm" // tech)
## 3/4 German; 1/4 eps are English
(fromDb "omegataupodcast.net" // tech)
## Lateral with Tom Scott
(mkPod "https://audioboom.com/channels/5097784.rss" // tech)
]; ];
texts = [ texts = [

View File

@@ -1,9 +1,10 @@
# docs # docs
# - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html> # - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html>
{ pkgs, sane-lib, ... }: { lib, pkgs, sane-lib, ... }:
let fsOpts = rec { let
fsOpts = rec {
common = [ common = [
"_netdev" "_netdev"
"noatime" "noatime"
@@ -54,9 +55,19 @@ let fsOpts = rec {
"timeo=15" "timeo=15"
"nofail" # don't fail remote-fs.target when this mount fails (not an option for sshfs else would be common) "nofail" # don't fail remote-fs.target when this mount fails (not an option for sshfs else would be common)
]; ];
}; };
remoteHome = host: {
fileSystems."/mnt/${host}-home" = {
device = "colin@${host}:/home/colin";
fsType = "fuse.sshfs";
options = fsOpts.sshColin ++ fsOpts.noauto;
noCheck = true;
};
sane.fs."/mnt/${host}-home" = sane-lib.fs.wantedDir;
};
in in
{ lib.mkMerge [
{
# some services which use private directories error if the parent (/var/lib/private) isn't 700. # some services which use private directories error if the parent (/var/lib/private) isn't 700.
sane.fs."/var/lib/private".dir.acl.mode = "0700"; sane.fs."/var/lib/private".dir.acl.mode = "0700";
@@ -100,6 +111,12 @@ in
fsType = "nfs"; fsType = "nfs";
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg; options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
}; };
fileSystems."/mnt/servo-nfs/playground" = {
device = "servo-hn:/playground";
noCheck = true;
fsType = "nfs";
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
};
# fileSystems."/mnt/servo-media-nfs" = { # fileSystems."/mnt/servo-media-nfs" = {
# device = "servo-hn:/media"; # device = "servo-hn:/media";
# noCheck = true; # noCheck = true;
@@ -108,21 +125,6 @@ in
# }; # };
sane.fs."/mnt/servo-media" = sane-lib.fs.wantedSymlinkTo "/mnt/servo-nfs/media"; sane.fs."/mnt/servo-media" = sane-lib.fs.wantedSymlinkTo "/mnt/servo-nfs/media";
fileSystems."/mnt/desko-home" = {
device = "colin@desko:/home/colin";
fsType = "fuse.sshfs";
options = fsOpts.sshColin ++ fsOpts.noauto;
noCheck = true;
};
sane.fs."/mnt/desko-home" = sane-lib.fs.wantedDir;
fileSystems."/mnt/desko-root" = {
device = "colin@desko:/";
fsType = "fuse.sshfs";
options = fsOpts.sshRoot ++ fsOpts.noauto;
noCheck = true;
};
sane.fs."/mnt/desko-root" = sane-lib.fs.wantedDir;
environment.pathsToLink = [ environment.pathsToLink = [
# needed to achieve superuser access for user-mounted filesystems (see optionsRoot above) # needed to achieve superuser access for user-mounted filesystems (see optionsRoot above)
# we can only link whole directories here, even though we're only interested in pkgs.openssh # we can only link whole directories here, even though we're only interested in pkgs.openssh
@@ -132,5 +134,10 @@ in
environment.systemPackages = [ environment.systemPackages = [
pkgs.sshfs-fuse pkgs.sshfs-fuse
]; ];
} }
(remoteHome "desko")
(remoteHome "lappy")
(remoteHome "moby")
]

View File

@@ -44,6 +44,8 @@
sane.ids.sftpgo.gid = 2410; sane.ids.sftpgo.gid = 2410;
sane.ids.trust-dns.uid = 2411; sane.ids.trust-dns.uid = 2411;
sane.ids.trust-dns.gid = 2411; sane.ids.trust-dns.gid = 2411;
sane.ids.export.gid = 2412;
sane.ids.nfsuser.uid = 2413;
sane.ids.colin.uid = 1000; sane.ids.colin.uid = 1000;
sane.ids.guest.uid = 1100; sane.ids.guest.uid = 1100;

View File

@@ -0,0 +1,24 @@
# alacritty terminal emulator
# - config options: <https://github.com/alacritty/alacritty/blob/master/extra/man/alacritty.5.scd>
# - `man 5 alacritty`
# - defaults: <https://github.com/alacritty/alacritty/releases> -> alacritty.yml
# - irc: #alacritty on libera.chat
{ lib, ... }:
{
sane.programs.alacritty = {
env.TERMINAL = lib.mkDefault "alacritty";
# note: alacritty will switch to .toml config in 13.0 release
# - run `alacritty migrate` to convert the yaml to toml
fs.".config/alacritty/alacritty.yml".symlink.text = ''
font:
size: 14
key_bindings:
- { key: N, mods: Control, action: CreateNewWindow }
- { key: PageUp, mods: Control, action: ScrollPageUp }
- { key: PageDown, mods: Control, action: ScrollPageDown }
- { key: PageUp, mods: Control|Shift, action: ScrollPageUp }
- { key: PageDown, mods: Control|Shift, action: ScrollPageDown }
'';
};
}

View File

@@ -51,6 +51,7 @@ in
]; ];
"sane-scripts.sys-utils" = declPackageSet [ "sane-scripts.sys-utils" = declPackageSet [
"sane-scripts.ip-port-forward" "sane-scripts.ip-port-forward"
"sane-scripts.sync-music"
]; ];
@@ -126,7 +127,7 @@ in
# "gopass" # "gopass"
# "gopass-jsonapi" # "gopass-jsonapi"
"helix" # text editor "helix" # text editor
"kitty" # TODO: move to GUI, but `ssh servo` from kitty sets `TERM=xterm-kitty` in the remove and breaks things # "kitty" # XXX needs to be in consolueUtils because `ssh servo` from kitty sets `TERM=xterm-kitty` in the remote and breaks things
"libsecret" # for managing user keyrings. TODO: what needs this? lift into the consumer "libsecret" # for managing user keyrings. TODO: what needs this? lift into the consumer
"lm_sensors" # for sensors-detect. TODO: what needs this? lift into the consumer "lm_sensors" # for sensors-detect. TODO: what needs this? lift into the consumer
"lshw" "lshw"
@@ -200,8 +201,6 @@ in
# INDIVIDUAL PACKAGE DEFINITIONS # INDIVIDUAL PACKAGE DEFINITIONS
dino.persist.private = [ ".local/share/dino" ];
# creds, but also 200 MB of node modules, etc # creds, but also 200 MB of node modules, etc
discord.persist.private = [ ".config/discord" ]; discord.persist.private = [ ".config/discord" ];

View File

@@ -0,0 +1,36 @@
# cantata is a mpd frontend.
# before launching it, run `mopidy` in some tab
# TODO: auto-launch mopidy when cantata launches?
{ ... }:
{
sane.programs.cantata = {
persist.plaintext = [
".cache/cantata" # album art
".local/share/cantata/library" # library index (?)
];
fs.".config/cantata/cantata.conf".symlink.text = ''
[General]
fetchCovers=true
storeCoversInMpdDir=false
version=2.5.0
[Connection]
allowLocalStreaming=true
applyReplayGain=true
autoUpdate=false
dir=~/Music
host=localhost
partition=
passwd=
port=6600
replayGain=off
streamUrl=
[LibraryPage]
artist\gridZoom=100
artist\searchActive=false
artist\viewMode=detailedtree
'';
suggestedPrograms = [ "mopidy" ];
};
}

View File

@@ -38,7 +38,9 @@ in
suggestedPrograms = [ "gnome-keyring" ]; suggestedPrograms = [ "gnome-keyring" ];
persist.private = [ persist.private = [
".local/share/chatty" # matrix avatars and files ".local/share/chatty" # matrix avatars and files
# ".purple" # XMPP stuff # not just XMPP; without this Chatty will regenerate its device-id every boot.
# .purple/ contains XMPP *and* Matrix auth, logs, avatar cache, and a bit more
".purple"
]; ];
}; };
} }

View File

@@ -3,9 +3,12 @@
{ {
imports = [ imports = [
./aerc.nix ./aerc.nix
./alacritty.nix
./assorted.nix ./assorted.nix
./cantata.nix
./chatty.nix ./chatty.nix
./cozy.nix ./cozy.nix
./dino.nix
./element-desktop.nix ./element-desktop.nix
./epiphany.nix ./epiphany.nix
./evince.nix ./evince.nix
@@ -13,9 +16,12 @@
./fontconfig.nix ./fontconfig.nix
./fractal.nix ./fractal.nix
./fwupd.nix ./fwupd.nix
./g4music.nix
./gajim.nix
./git.nix ./git.nix
./gnome-feeds.nix ./gnome-feeds.nix
./gnome-keyring.nix ./gnome-keyring.nix
./gnome-weather.nix
./gpodder.nix ./gpodder.nix
./gthumb.nix ./gthumb.nix
./helix.nix ./helix.nix
@@ -28,6 +34,7 @@
./lemoa.nix ./lemoa.nix
./megapixels.nix ./megapixels.nix
./mepo.nix ./mepo.nix
./mopidy.nix
./mpv.nix ./mpv.nix
./msmtp.nix ./msmtp.nix
./neovim.nix ./neovim.nix
@@ -36,6 +43,7 @@
./nix-index.nix ./nix-index.nix
./obsidian.nix ./obsidian.nix
./offlineimap.nix ./offlineimap.nix
./rhythmbox.nix
./ripgrep.nix ./ripgrep.nix
./sfeed.nix ./sfeed.nix
./splatmoji.nix ./splatmoji.nix

View File

@@ -0,0 +1,15 @@
# usage:
# - start a DM with a rando via
# - '+' -> 'start conversation'
# - add a user to your roster via
# - '+' -> 'start conversation' -> '+' (opens the "add contact" dialog)
# - this triggers a popup on the remote side asking them for confirmation
# - after the remote's confirmation there will be a local popup for you to allow them to add you to their roster
# - to make a call:
# - ensure the other party is in your roster
# - open a DM with the party
# - click the phone icon at top (only visible if other party is in your roster)
{ ... }:
{
sane.programs.dino.persist.private = [ ".local/share/dino" ];
}

View File

@@ -0,0 +1,16 @@
# N.B.: requires first-run setup on moby:
# - UI will render transparent
# - click the hamburger (top-right: immediately left from close button)
# > Preferences
# > Background-blur mode: change from "Always" to "Never"
#
# the background blur is probably some dconf setting somewhere.
{ ... }:
{
sane.programs.g4music = {
persist.plaintext = [
# index?
".cache/com.github.neithern.g4music"
];
};
}

View File

@@ -0,0 +1,13 @@
{ ... }:
{
sane.programs.gajim = {
persist.private = [
# avatars, thumbnails...
".cache/gajim"
# sqlite database labeled "settings". definitely includes UI theming
".config/gajim"
# omemo keys, downloads, logs
".local/share/gajim"
];
};
}

View File

@@ -0,0 +1,10 @@
# preferences are saved via dconf; see `dconf dump /`
# cache dir is just for weather data (or maybe a http cache)
{ ... }:
{
sane.programs.gnome-weather = {
persist.plaintext = [
".cache/libgweather"
];
};
}

View File

@@ -4,10 +4,12 @@
# compile without webservices to avoid the expensive webkitgtk dependency # compile without webservices to avoid the expensive webkitgtk dependency
package = pkgs.gthumb.override { withWebservices = false; }; package = pkgs.gthumb.override { withWebservices = false; };
mime.associations = { mime.associations = {
"image/gif" = "org.gnome.gThumb.desktop";
"image/heif" = "org.gnome.gThumb.desktop"; # apple codec "image/heif" = "org.gnome.gThumb.desktop"; # apple codec
"image/png" = "org.gnome.gThumb.desktop"; "image/png" = "org.gnome.gThumb.desktop";
"image/jpeg" = "org.gnome.gThumb.desktop"; "image/jpeg" = "org.gnome.gThumb.desktop";
"image/svg+xml" = "org.gnome.gThumb.desktop"; "image/svg+xml" = "org.gnome.gThumb.desktop";
"image/webp" = "org.gnome.gThumb.desktop";
}; };
}; };
} }

View File

@@ -0,0 +1,56 @@
# chat: <https://mopidy.zulipchat.com/>
# config docs: <https://docs.mopidy.com/en/latest/config/>
# web client: <http://localhost:6680>
# mpd: hosted on `localhost:6600`, no password`
#
# dump config:
# - `mopidy config`
# update local file index with
# - `mopidy local scan`
#
# if running as service, those commands are `mopidy --config ... <command>`
# and config path is found by `systemctl cat mopidy`
{ config, lib, pkgs, ... }:
let
# TODO: upstream this as `mopidy.withExtensions`
# this is borrowed from the nixos mopidy service
mopidyWithExtensions = extensions: with pkgs; buildEnv {
name = "mopidy-with-extensions-${mopidy.version}";
paths = lib.closePropagation extensions;
pathsToLink = [ "/${mopidyPackages.python.sitePackages}" ];
nativeBuildInputs = [ makeWrapper ];
postBuild = ''
makeWrapper ${mopidy}/bin/mopidy $out/bin/mopidy \
--prefix PYTHONPATH : $out/${mopidyPackages.python.sitePackages}
'';
};
in
{
sane.programs.mopidy = {
package = mopidyWithExtensions (with pkgs; [
mopidy-iris # web client: <https://github.com/jaedb/Iris>
mopidy-jellyfin
mopidy-local
mopidy-mpd
mopidy-mpris
mopidy-spotify
# TODO: mopidy-podcast, mopidy-youtube
# alternate web clients:
# mopidy-moped: <https://github.com/martijnboland/moped>
# mopidy-muse: <https://github.com/cristianpb/muse>
]);
persist.plaintext = [
".local/share/mopidy/local" # thumbs, library db
];
persist.private = [
".local/share/mopidy/http" # cookie
];
secrets.".config/mopidy/mopidy.conf" = ../../../secrets/common/mopidy.conf.bin;
# other folders:
# - .cache/mopidy
# - .config/mopidy
};
}

View File

@@ -14,6 +14,29 @@
# uosc # uosc
pkgs.mpv-uosc-latest pkgs.mpv-uosc-latest
]; ];
extraMakeWrapperArgs = [
# 2023/08/29: fixes an error where mpv on moby launches with the message
# "DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory"
# audio still works, and controls, screenshotting, etc -- just not the actual rendering
# this is likely a regression for mpv 0.36.0.
# the actual error message *appears* to come from the mesa library, but it's tough to trace.
# run with `--vo=help` to see a list of all output options.
# non-exhaustive (F=fails, W=works)
# ? libmpv render API for libmpv
# ? gpu Shader-based GPU Renderer
# ? gpu-next Video output based on libplacebo
# ? vdpau VDPAU with X11
# ? wlshm Wayland SHM video output (software scaling)
# ? xv X11/Xv
# W sdl SDL 2.0 Renderer
# F dmabuf-wayland Wayland dmabuf video output
# ? vaapi VA API with X11
# ? x11 X11 (software scaling)
# ? null Null video output
# ? caca libcaca
# F drm Direct Rendering Manager (software scaling)
"--add-flags" "--vo=sdl"
];
}; };
persist.plaintext = [ ".config/mpv/watch_later" ]; persist.plaintext = [ ".config/mpv/watch_later" ];
fs.".config/mpv/input.conf".symlink.text = '' fs.".config/mpv/input.conf".symlink.text = ''
@@ -26,6 +49,10 @@
save-position-on-quit=yes save-position-on-quit=yes
keep-open=yes keep-open=yes
# force GUI, even for tracks w/o album art
# see: <https://www.reddit.com/r/mpv/comments/rvrrpt/oscosdgui_and_arch_linux/>
player-operation-mode=pseudo-gui
# use uosc instead (for On Screen Controls) # use uosc instead (for On Screen Controls)
osc=no osc=no
# uosc provides its own seeking/volume indicators, so you also don't need this # uosc provides its own seeking/volume indicators, so you also don't need this

View File

@@ -0,0 +1,11 @@
{ ... }:
{
sane.programs.rhythmbox = {
persist.plaintext = [
# playlists; index
".local/share/rhythmbox"
# album art
".cache/rhythmbox"
];
};
}

View File

@@ -7,6 +7,7 @@
# - $ZDOTDIR/.zprofile # - $ZDOTDIR/.zprofile
# - if interactive: # - if interactive:
# - /etc/zshrc # - /etc/zshrc
# -> /etc/zinputrc
# - $ZDOTDIR/.zshrc # - $ZDOTDIR/.zshrc
# - if login (again): # - if login (again):
# - /etc/zlogin # - /etc/zlogin
@@ -79,6 +80,18 @@ in
hash -d tmp="/home/colin/tmp" hash -d tmp="/home/colin/tmp"
hash -d uninsane="/home/colin/dev/uninsane" hash -d uninsane="/home/colin/dev/uninsane"
hash -d Videos="/home/colin/Videos" hash -d Videos="/home/colin/Videos"
# emulate bash keybindings
bindkey -e
# or manually recreate what i care about...
# key[Left]=''${terminfo[kcub1]}
# key[Right]=''${terminfo[kcuf1]}
# bindkey '^R' history-incremental-search-backward
# bindkey '^A' beginning-of-line
# bindkey '^E' end-of-line
# bindkey "^''${key[Left]}" backward-word
# bindkey "^''${key[Right]}" forward-word
''; '';
}; };
}) })

View File

@@ -28,21 +28,26 @@
{ config, lib, sane-lib, ... }: { config, lib, sane-lib, ... }:
let let
inherit (lib.strings) hasSuffix removeSuffix;
secretsForHost = host: let secretsForHost = host: let
extraAttrsForPath = path: lib.optionalAttrs (sane-lib.path.isChild "guest" path && builtins.hasAttr "guest" config.users.users) { extraAttrsForPath = path: lib.optionalAttrs (sane-lib.path.isChild "guest" path && builtins.hasAttr "guest" config.users.users) {
owner = "guest"; owner = "guest";
}; };
secretsInSrc = (
if builtins.pathExists ../../secrets/${host} then
sane-lib.enumerateFilePaths ../../secrets/${host}
else
[]
);
in sane-lib.joinAttrsets ( in sane-lib.joinAttrsets (
map map
(path: lib.optionalAttrs (hasSuffix ".bin" path) (sane-lib.nameValueToAttrs { (path: lib.optionalAttrs (lib.hasSuffix ".bin" path) (sane-lib.nameValueToAttrs {
name = removeSuffix ".bin" path; name = lib.removeSuffix ".bin" path;
value = { value = {
sopsFile = ../../secrets/${host}/${path}; sopsFile = ../../secrets/${host}/${path};
format = "binary"; format = "binary";
} // (extraAttrsForPath path); } // (extraAttrsForPath path);
})) }))
(sane-lib.enumerateFilePaths ../../secrets/${host}) secretsInSrc
); );
in in
{ {

View File

@@ -16,6 +16,7 @@
group = "users"; group = "users";
extraGroups = [ extraGroups = [
"dialout" # required for modem access (moby) "dialout" # required for modem access (moby)
"export" # to read filesystem exports (servo)
"feedbackd" "feedbackd"
"input" # for /dev/input/<xyz>: sxmo "input" # for /dev/input/<xyz>: sxmo
"networkmanager" "networkmanager"
@@ -83,7 +84,7 @@
fs."Books/servo".symlink.target = "/mnt/servo-media/Books"; fs."Books/servo".symlink.target = "/mnt/servo-media/Books";
fs."Videos/servo".symlink.target = "/mnt/servo-media/Videos"; fs."Videos/servo".symlink.target = "/mnt/servo-media/Videos";
fs."Videos/servo-incomplete".symlink.target = "/mnt/servo-media/incomplete"; fs."Videos/servo-incomplete".symlink.target = "/mnt/servo-media/incomplete";
fs."Music/servo".symlink.target = "/mnt/servo-media/Music"; # fs."Music/servo".symlink.target = "/mnt/servo-media/Music";
fs."Pictures/servo-macros".symlink.target = "/mnt/servo-media/Pictures/macros"; fs."Pictures/servo-macros".symlink.target = "/mnt/servo-media/Pictures/macros";
# used by password managers, e.g. unix `pass` # used by password managers, e.g. unix `pass`

View File

@@ -2,6 +2,7 @@
{ {
imports = [ imports = [
./gnome.nix ./gnome.nix
./greetd.nix
./gtk.nix ./gtk.nix
./phosh.nix ./phosh.nix
./sway ./sway
@@ -16,15 +17,18 @@
# package sets # package sets
"tuiApps" "tuiApps"
] ++ [ ] ++ [
"alacritty" # terminal emulator
# "celluloid" # mpv frontend # "celluloid" # mpv frontend
"chatty" # matrix/xmpp/irc client "chatty" # matrix/xmpp/irc client
"cozy" # audiobook player "cozy" # audiobook player
"dino" # XMPP client
# "emote" # "emote"
"epiphany" # gnome's web browser "epiphany" # gnome's web browser
"evince" # works on phosh "evince" # works on phosh
"firefox" "firefox"
# "foliate" # e-book reader # "foliate" # e-book reader
# "fractal" # matrix client # "fractal" # matrix client
"g4music" # local music player
# "gnome.cheese" # "gnome.cheese"
# "gnome-feeds" # RSS reader (with claimed mobile support) # "gnome-feeds" # RSS reader (with claimed mobile support)
# "gnome.file-roller" # "gnome.file-roller"
@@ -32,16 +36,16 @@
# "gnome-podcasts" # "gnome-podcasts"
# "gnome.gnome-system-monitor" # "gnome.gnome-system-monitor"
# "gnome.gnome-terminal" # works on phosh # "gnome.gnome-terminal" # works on phosh
# "gnome.gnome-weather" "gnome.gnome-weather"
"gpodder" "gpodder"
"gthumb" "gthumb"
"komikku" "komikku"
"koreader" "koreader"
"lemoa" # lemmy app "lemoa" # lemmy app
# "lollypop" # "lollypop"
"mate.engrampa" # archive manager
"mepo" # maps viewer "mepo" # maps viewer
"mpv" "mpv"
"nheko"
# "networkmanagerapplet" # "networkmanagerapplet"
# "newsflash" # "newsflash"
"pavucontrol" "pavucontrol"
@@ -64,28 +68,30 @@
"audacity" "audacity"
"blanket" # ambient noise generator "blanket" # ambient noise generator
"brave" # for the integrated wallet -- as a backup "brave" # for the integrated wallet -- as a backup
"cantata" # music player (mpd frontend)
# "chromium" # chromium takes hours to build. brave is chromium-based, distributed in binary form, so prefer it. # "chromium" # chromium takes hours to build. brave is chromium-based, distributed in binary form, so prefer it.
# "dino" # XMPP client
"electrum" "electrum"
"element-desktop" "element-desktop"
# "font-manager" #< depends on webkitgtk4_0 (expensive to build) # "font-manager" #< depends on webkitgtk4_0 (expensive to build)
# "gajim" # XMPP client "gajim" # XMPP client. cross build tries to import host gobject-introspection types (2023/09/01)
"gimp" # broken on phosh "gimp" # broken on phosh
"gnome.dconf-editor" "gnome.dconf-editor"
"gnome.file-roller" # "gnome.file-roller"
"gnome.gnome-disk-utility" "gnome.gnome-disk-utility"
"gnome.nautilus" # file browser "gnome.nautilus" # file browser
# "gnome.totem" # video player, supposedly supports UPnP # "gnome.totem" # video player, supposedly supports UPnP
"handbrake" "handbrake"
"hase" "hase"
"inkscape" "inkscape"
"jellyfin-media-player" # "jellyfin-media-player"
"kdenlive" "kdenlive"
"kid3" # audio tagging "kid3" # audio tagging
"krita" "krita"
"libreoffice" # TODO: replace with an office suite that uses saner packaging? "libreoffice" # TODO: replace with an office suite that uses saner packaging?
"mumble" "mumble"
"nheko"
"obsidian" "obsidian"
"rhythmbox" # local music player
"slic3r" "slic3r"
"steam" "steam"
"vlc" "vlc"

View File

@@ -0,0 +1,128 @@
# greetd source/docs:
# - <https://git.sr.ht/~kennylevinsen/greetd>
{ config, lib, pkgs, ... }:
let
systemd-cat = "${pkgs.systemd}/bin/systemd-cat";
runWithLogger = identifier: cmd: pkgs.writeShellScriptBin identifier ''
echo "launching ${identifier}..." | ${systemd-cat} --identifier=${identifier}
${cmd} 2>&1 | ${systemd-cat} --identifier=${identifier}
'';
cfg = config.sane.gui.greetd;
in
{
options = with lib; {
sane.gui.greetd.enable = mkOption {
default = false;
type = types.bool;
};
sane.gui.greetd.session.command = mkOption {
type = types.str;
description = ''
name to use for the default session in syslog.
'';
};
sane.gui.greetd.session.name = mkOption {
default = "greetd-session";
type = types.str;
description = "name of session to use in logger";
};
sane.gui.greetd.session.user = mkOption {
default = null;
type = types.nullOr types.str;
};
# helpers for common things to layer on top of greetd
sane.gui.greetd.sway.enable = mkOption {
default = false;
type = types.bool;
description = ''
use sway as a wayland compositor in which to host a graphical greeter like gtkgreet, phog, etc.
'';
};
sane.gui.greetd.sway.greeterCmd = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
command for sway to `exec` that provides the actual graphical greeter.
'';
};
sane.gui.greetd.sway.gtkgreet.enable = mkOption {
default = false;
type = types.bool;
description = ''
have sway launch gtkgreet instead of directly presenting a desktop.
'';
};
sane.gui.greetd.sway.gtkgreet.session.command = mkOption {
type = types.str;
description = ''
command for gtkgreet to execute on successful authentication.
'';
};
sane.gui.greetd.sway.gtkgreet.session.name = mkOption {
type = types.str;
description = ''
name to use for the default session in syslog and in the gtkgreet menu.
note that this `sessionName` will become a binary on the user's PATH.
'';
};
sane.gui.greetd.sway.gtkgreet.session.user = mkOption {
type = types.str;
default = "colin";
description = ''
name of user which one expects to login as.
'';
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
(lib.mkIf cfg.sway.enable {
sane.gui.greetd.session = if cfg.sway.greeterCmd != null then {
name = "sway-as-greeter";
command = let
swayAsGreeterConfig = pkgs.writeText "sway-as-greeter-config" ''
exec ${cfg.sway.greeterCmd}
'';
in "${pkgs.sway}/bin/sway --debug --config ${swayAsGreeterConfig}";
} else {
name = "sway";
user = lib.mkDefault "colin";
command = "${pkgs.sway}/bin/sway --debug";
};
})
(lib.mkIf cfg.sway.gtkgreet.enable (
let
inherit (cfg.sway.gtkgreet) session;
sessionProvider = runWithLogger session.name session.command;
in {
# gtkgreet shows the --command argument in the UI
# - so we want it to look nice (not a /nix/store/... path)
# - to do that we put it in the user's PATH.
sane.gui.greetd.sway.greeterCmd = "${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command ${session.name}";
users.users.${session.user}.packages = [ sessionProvider ];
}
))
{
services.greetd = {
enable = true;
# i could have gtkgreet launch the session directly: but stdout/stderr gets dropped
# settings.default_session.command = cfg.session.command;
# wrapper to launch with stdout/stderr redirected to system journal.
settings.default_session.command = let
launchWithLogger = runWithLogger cfg.session.name cfg.session.command;
in "${launchWithLogger}/bin/${cfg.session.name}";
};
# persisting fontconfig & mesa_shader_cache improves start time by ~5x
users.users.greeter.home = "/var/lib/greeter";
sane.persist.sys.plaintext = [
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/fontconfig"; }
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/mesa_shader_cache"; }
];
}
]);
}

View File

@@ -5,11 +5,15 @@ https://nixos.org/manual/nix/stable/language/builtins.html
https://github.com/nixos/nixpkgs/pulls?q= https://github.com/nixos/nixpkgs/pulls?q=
https://nur.nix-community.org/ https://nur.nix-community.org/
https://nix-community.github.io/home-manager/options.html https://nix-community.github.io/home-manager/options.html
https://lists.sr.ht/~mil/sxmo-devel
https://w.uninsane.org/viewer#search?books.name=wikipedia_en_all_maxi_2022-05&pattern= https://w.uninsane.org/viewer#search?books.name=wikipedia_en_all_maxi_2022-05&pattern=
https://jackett.uninsane.org/UI/Dashboard#search= https://jackett.uninsane.org/UI/Dashboard#search=
https://lemmy.uninsane.org
https://fed.uninsane.org https://fed.uninsane.org
https://jelly.uninsane.org
https://bt.uninsane.org https://bt.uninsane.org
https://sci-hub.se https://sci-hub.se
https://archive.is https://archive.is
https://news.ycombinator.com https://news.ycombinator.com
http://10.78.79.1 # Router/Firewall http://10.78.79.1 # router/firewall
https://jochen-hoenicke.de/queue # johoe's mempool (bitcoin/ethereum)

View File

@@ -1,44 +1,12 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
# docs: https://nixos.wiki/wiki/Sway # docs: https://nixos.wiki/wiki/Sway
with lib; # sway-config docs: `man 5 sway`
let let
cfg = config.sane.gui.sway; cfg = config.sane.gui.sway;
# bare sway launcher
sway-launcher = pkgs.writeShellScriptBin "sway-launcher" ''
${pkgs.sway}/bin/sway --debug > /var/log/sway/sway.log 2>&1
'';
# start sway and have it construct the gtkgreeter
sway-as-greeter = pkgs.writeShellScriptBin "sway-as-greeter" ''
${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet} > /var/log/sway/sway-as-greeter.log 2>&1
'';
# (config file for the above)
sway-config-into-gtkgreet = pkgs.writeText "greetd-sway-config" ''
exec "${gtkgreet-launcher}"
'';
# gtkgreet which launches a layered sway instance
gtkgreet-launcher = pkgs.writeShellScript "gtkgreet-launcher" ''
# NB: the "command" field here is run in the user's shell.
# so that command must exist on the specific user's path who is logging in. it doesn't need to exist system-wide.
${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command sway-launcher
'';
greeter-session = {
# greeter session config
command = "${sway-as-greeter}/bin/sway-as-greeter";
# alternatives:
# - TTY: `command = "${pkgs.greetd.greetd}/bin/agreety --cmd ${pkgs.sway}/bin/sway";`
# - autologin: `command = "${pkgs.sway}/bin/sway"; user = "colin";`
# - Dumb Login (doesn't work)": `command = "${pkgs.greetd.dlm}/bin/dlm";`
};
greeterless-session = {
# no greeter
command = "${sway-launcher}/bin/sway-launcher";
user = "colin";
};
in in
{ {
options = { options = with lib; {
sane.gui.sway.enable = mkOption { sane.gui.sway.enable = mkOption {
default = false; default = false;
type = types.bool; type = types.bool;
@@ -51,8 +19,16 @@ in
default = true; default = true;
type = types.bool; type = types.bool;
}; };
sane.gui.sway.installConfigs = mkOption {
default = true;
type = types.bool;
description = ''
populate ~/.config/sway/config & co with defaults provided by this module.
'';
}; };
config = mkMerge [ };
config = lib.mkMerge [
{ {
sane.programs.swayApps = { sane.programs.swayApps = {
package = null; package = null;
@@ -75,11 +51,9 @@ in
}; };
} }
(mkIf cfg.enable { (lib.mkIf cfg.enable {
sane.programs.fontconfig.enableFor.system = true; sane.programs.fontconfig.enableFor.system = true;
sane.programs.swayApps.enableFor.user.colin = true; sane.programs.swayApps.enableFor.user.colin = true;
# we need the greeter's command to be on our PATH
users.users.colin.packages = [ sway-launcher ];
sane.gui.gtk.enable = lib.mkDefault true; sane.gui.gtk.enable = lib.mkDefault true;
# sane.gui.gtk.gtk-theme = lib.mkDefault "Fluent-Light-compact"; # sane.gui.gtk.gtk-theme = lib.mkDefault "Fluent-Light-compact";
@@ -88,13 +62,12 @@ in
# swap in these lines to use SDDM instead of `services.greetd`. # swap in these lines to use SDDM instead of `services.greetd`.
# services.xserver.displayManager.sddm.enable = true; # services.xserver.displayManager.sddm.enable = true;
# services.xserver.enable = true; # services.xserver.enable = true;
services.greetd = { sane.gui.greetd.enable = true;
# greetd source/docs: sane.gui.greetd.sway.enable = true; # have greetd launch a sway compositor in which we host a greeter
# - <https://git.sr.ht/~kennylevinsen/greetd> sane.gui.greetd.sway.gtkgreet = lib.mkIf cfg.useGreeter {
enable = true; enable = true;
settings = { session.name = "sway-on-gtkgreet";
default_session = if cfg.useGreeter then greeter-session else greeterless-session; session.command = "${pkgs.sway}/bin/sway --debug";
};
}; };
# unlike other DEs, sway configures no audio stack # unlike other DEs, sway configures no audio stack
@@ -103,6 +76,7 @@ in
enable = true; enable = true;
alsa.enable = true; alsa.enable = true;
alsa.support32Bit = true; # ?? alsa.support32Bit = true; # ??
# emulate pulseaudio for legacy apps (e.g. sxmo-utils)
pulse.enable = true; pulse.enable = true;
}; };
@@ -124,11 +98,6 @@ in
# a system service can't depend on a user service, so just launch it at graphical-session # a system service can't depend on a user service, so just launch it at graphical-session
systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ]; systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ];
sane.fs."/var/log/sway" = {
dir.acl.mode = "0777";
wantedBeforeBy = [ "greetd.service" "display-manager.service" ];
};
programs.sway = { programs.sway = {
# provides xdg-desktop-portal-wlr, which exposes on dbus: # provides xdg-desktop-portal-wlr, which exposes on dbus:
# - org.freedesktop.impl.portal.ScreenCast # - org.freedesktop.impl.portal.ScreenCast
@@ -162,17 +131,19 @@ in
}) })
]; ];
sane.user.fs.".config/sway/config".symlink.text = sane.user.fs = lib.mkIf cfg.installConfigs {
".config/sway/config".symlink.text =
import ./sway-config.nix { inherit pkgs; }; import ./sway-config.nix { inherit pkgs; };
sane.user.fs.".config/waybar/config".symlink.target = ".config/waybar/config".symlink.target =
let let
waybar-config = import ./waybar-config.nix { inherit pkgs; }; waybar-config = import ./waybar-config.nix { inherit pkgs; };
in in
(pkgs.formats.json {}).generate "waybar-config.json" waybar-config; (pkgs.formats.json {}).generate "waybar-config.json" waybar-config;
sane.user.fs.".config/waybar/style.css".symlink.text = ".config/waybar/style.css".symlink.text =
builtins.readFile ./waybar-style.css; builtins.readFile ./waybar-style.css;
};
}) })
]; ];
} }

View File

@@ -3,9 +3,8 @@ let
fuzzel = "${pkgs.fuzzel}/bin/fuzzel"; fuzzel = "${pkgs.fuzzel}/bin/fuzzel";
sed = "${pkgs.gnused}/bin/sed"; sed = "${pkgs.gnused}/bin/sed";
wtype = "${pkgs.wtype}/bin/wtype"; wtype = "${pkgs.wtype}/bin/wtype";
kitty = "${pkgs.kitty}/bin/kitty";
launcher-cmd = fuzzel; launcher-cmd = fuzzel;
terminal-cmd = kitty; terminal-cmd = "${pkgs.xdg-terminal-exec}/bin/xdg-terminal-exec";
lock-cmd = "${pkgs.swaylock}/bin/swaylock --indicator-idle-visible --indicator-radius 100 --indicator-thickness 30"; lock-cmd = "${pkgs.swaylock}/bin/swaylock --indicator-idle-visible --indicator-radius 100 --indicator-thickness 30";
vol-up-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5"; vol-up-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5";
vol-down-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5"; vol-down-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5";
@@ -25,6 +24,8 @@ let
# mod = "Mod1"; # Alt # mod = "Mod1"; # Alt
mod = "Mod4"; # Super mod = "Mod4"; # Super
in '' in ''
# xwayland disable
### default font ### default font
font pango:monospace 8 font pango:monospace 8
@@ -33,13 +34,12 @@ in ''
default_floating_border pixel 2 default_floating_border pixel 2
hide_edge_borders smart hide_edge_borders smart
### defaults #### focus_wrapping: behavior when trying to focus past the edge of a container
#### no => preserve last focus. helpful mostly when `focus_follows_mouse yes`
focus_wrapping no focus_wrapping no
focus_follows_mouse yes focus_follows_mouse yes
focus_on_window_activation smart #### workspace_layout default => workspaces use splits by default (as opposed to e.g. tabbed)
mouse_warping output
workspace_layout default workspace_layout default
workspace_auto_back_and_forth no
### default colors (#border #background #text #indicator #childBorder) ### default colors (#border #background #text #indicator #childBorder)
client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577 client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577

View File

@@ -1,5 +1,3 @@
-- configversion: 737cb1de0389cee32a04785691a446a2
-- docs: <https://conky.cc/variables> -- docs: <https://conky.cc/variables>
-- color names are X11 colors: <https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart> -- color names are X11 colors: <https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart>
-- - can also use #rrggbb syntax -- - can also use #rrggbb syntax
@@ -37,12 +35,14 @@ conky.config = {
color2 = '404040', color2 = '404040',
} }
-- texeci <interval_sec> <cmd>: run the command periodically, _in a separate thread_ so as not to block rendering
conky.text = [[ conky.text = [[
${color1}${shadecolor 707070}${font Sxmo:size=50:style=Bold}${alignc}${exec date +"%H:%M"}${font} ${color1}${shadecolor 707070}${font Sxmo:size=50:style=Bold}${alignc}${exec date +"%H:%M"}${font}
${color2}${shadecolor a4d7d0}${font Sxmo:size=20}${alignc}${exec date +"%a %d %b"}${font} ${color2}${shadecolor a4d7d0}${font Sxmo:size=20}${alignc}${exec date +"%a %d %b"}${font}
${color1}${shadecolor}${font Sxmo:size=22:style=Bold}${alignc}${exec @bat@ }${font} ${color1}${shadecolor}${font Sxmo:size=22:style=Bold}${alignc}${exec @bat@ }${font}
${color1}${shadecolor}${font Sxmo:size=20:style=Bold}${alignc}${texeci 600 @weather@ }${font}
${color2}${shadecolor a4d7d0}${font Sxmo:size=16}${alignc}⇅ ${downspeedf wlan0}K/s${font} ${color2}${shadecolor a4d7d0}${font Sxmo:size=16}${alignc}⇅ ${downspeedf wlan0}K/s${font}

View File

@@ -37,7 +37,7 @@
# - live in ~/.local/state/sxmo.log # - live in ~/.local/state/sxmo.log
# - ~/.local/state/superd.log # - ~/.local/state/superd.log
# - ~/.local/state/superd/logs/<daemon>.log # - ~/.local/state/superd/logs/<daemon>.log
# - `journalctl --user --boot` (lightm redirects the sxmo session stdout => systemd) # - `journalctl --user --boot` (lightdm redirects the sxmo session stdout => systemd)
# #
# - default components: # - default components:
# - DE: sway (if wayland), dwm (if X) # - DE: sway (if wayland), dwm (if X)
@@ -45,6 +45,10 @@
# - gestures: lisgd # - gestures: lisgd
# - on-screen keyboard: wvkbd (if wayland), svkbd (if X) # - on-screen keyboard: wvkbd (if wayland), svkbd (if X)
# #
# TODO:
# - don't duplicate so much of hosts/modules/gui/sway
# - might help if i bring more under my control, and launch sxmo via sway instead of the opposite
# - theme `mako` notifications
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
@@ -57,6 +61,12 @@ let
knownTerminals = { knownTerminals = {
vte = "vte-2.91"; vte = "vte-2.91";
}; };
systemd-cat = "${pkgs.systemd}/bin/systemd-cat";
runWithLogger = identifier: cmd: pkgs.writeShellScript identifier ''
echo "launching ${identifier}..." | ${systemd-cat} --identifier=${identifier}
${cmd} 2>&1 | ${systemd-cat} --identifier=${identifier}
'';
in in
{ {
options = with lib; { options = with lib; {
@@ -65,17 +75,29 @@ in
type = types.bool; type = types.bool;
}; };
sane.gui.sxmo.greeter = mkOption { sane.gui.sxmo.greeter = mkOption {
type = types.enum [ "lightdm-mobile" "sway" ]; type = types.enum [
default = "lightdm-mobile"; "greetd-phog"
"greetd-sway-gtkgreet"
"greetd-sway-phog"
"greetd-sxmo"
"lightdm-mobile"
];
# default = "lightdm-mobile";
default = "greetd-sway-phog";
description = '' description = ''
which greeter to use. which greeter to use.
"greetd-phog" => phosh-based greeter. keypad (0-9) with option to open an on-screen keyboard.
"greetd-sway-phog" => phog, but uses sway as the compositor instead of phoc.
requires a patched phog, since sway doesn't provide the Wayland global "zphoc_layer_shell_effects_v1".
"greetd-sxmo" => launch sxmo directly from greetd, no auth.
this means no keychain unlocked or encrypted home mounted.
"lightdm-mobile" => keypad style greeter. can only enter digits 0-9 as password. "lightdm-mobile" => keypad style greeter. can only enter digits 0-9 as password.
"sway" => layered sway greeter. behaves as if you booted to swaylock. "greetd-sway-gtkgreet" => layered sway greeter. keyboard-only user/pass input; impractical on mobile.
''; '';
}; };
sane.gui.sxmo.package = mkOption { sane.gui.sxmo.package = mkOption {
type = types.package; type = types.package;
default = pkgs.sxmo-utils; default = pkgs.sxmo-utils-latest;
description = '' description = ''
sxmo base scripts and hooks collection. sxmo base scripts and hooks collection.
consider overriding the outputs under /share/sxmo/default_hooks consider overriding the outputs under /share/sxmo/default_hooks
@@ -116,7 +138,9 @@ in
}; };
in { in {
SXMO_BAR_SHOW_BAT_PER = mkSettingsOpt "1" "show battery percentage in statusbar"; SXMO_BAR_SHOW_BAT_PER = mkSettingsOpt "1" "show battery percentage in statusbar";
SXMO_DISABLE_CONFIGVERSION_CHECK = mkSettingsOpt "1" "allow omitting the configversion line from user-provided sxmo dotfiles";
SXMO_UNLOCK_IDLE_TIME = mkSettingsOpt "300" "how many seconds of inactivity before locking the screen"; # lock -> screenoff happens 8s later, not configurable SXMO_UNLOCK_IDLE_TIME = mkSettingsOpt "300" "how many seconds of inactivity before locking the screen"; # lock -> screenoff happens 8s later, not configurable
# SXMO_WM = mkSettingsOpt "sway" "sway or dwm. ordinarily initialized by sxmo_{x,w}init.sh";
}; };
}; };
default = {}; default = {};
@@ -139,8 +163,11 @@ in
package = null; package = null;
suggestedPrograms = [ suggestedPrograms = [
"guiApps" "guiApps"
"mako" # notification daemon
"sfeed" # want this here so that the user's ~/.sfeed/sfeedrc gets created "sfeed" # want this here so that the user's ~/.sfeed/sfeedrc gets created
"superd" # make superctl (used by sxmo) be on PATH "superd" # make superctl (used by sxmo) be on PATH
"sway-contrib.grimshot"
"wdisplays" # like xrandr
]; ];
persist.cryptClearOnBoot = [ persist.cryptClearOnBoot = [
@@ -160,20 +187,20 @@ in
(lib.mkIf cfg.enable (lib.mkMerge [ (lib.mkIf cfg.enable (lib.mkMerge [
{ {
sane.gui.sway = {
enable = true;
# we manage these ourselves (TODO: merge these into sway config as well)
useGreeter = false;
installConfigs = false;
};
sane.programs.sxmoApps.enableFor.user.colin = true; sane.programs.sxmoApps.enableFor.user.colin = true;
sane.gui.gtk.enable = lib.mkDefault true;
# sxmo internally uses doas instead of sudo # sxmo internally uses doas instead of sudo
security.doas.enable = true; security.doas.enable = true;
security.doas.wheelNeedsPassword = false; security.doas.wheelNeedsPassword = false;
# TODO: move this further to the host-specific config? hardware.opengl.enable = true;
networking.useDHCP = false;
networking.networkmanager.enable = true;
networking.wireless.enable = lib.mkForce false;
hardware.bluetooth.enable = true;
services.blueman.enable = true;
# TODO: nerdfonts is 4GB. it accepts an option to ship only some fonts: probably want to use that. # TODO: nerdfonts is 4GB. it accepts an option to ship only some fonts: probably want to use that.
fonts.packages = [ pkgs.nerdfonts ]; fonts.packages = [ pkgs.nerdfonts ];
@@ -181,21 +208,11 @@ in
# lightdm-mobile-greeter: "The name org.a11y.Bus was not provided by any .service files" # lightdm-mobile-greeter: "The name org.a11y.Bus was not provided by any .service files"
services.gnome.at-spi2-core.enable = true; services.gnome.at-spi2-core.enable = true;
# sxmo has first-class support only for pulseaudio and alsa -- not pipewire.
# however, pipewire can emulate pulseaudio support via `services.pipewire.pulse.enable = true`
# after which the stock pulseaudio binaries magically work
# administer with pw-cli, pw-mon, pw-top commands
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true; # ??
pulse.enable = true;
};
systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ];
# TODO: could use `displayManager.sessionPackages`? # TODO: could use `displayManager.sessionPackages`?
environment.systemPackages = [ environment.systemPackages = [
cfg.package cfg.package
pkgs.bonsai # sway (not sxmo) needs to exec `bonsaictl` by name (sxmo_swayinitconf.sh)
] ++ lib.optionals (cfg.terminal != null) [ pkgs."${cfg.terminal}" ] ] ++ lib.optionals (cfg.terminal != null) [ pkgs."${cfg.terminal}" ]
++ lib.optionals (cfg.keyboard != null) [ pkgs."${cfg.keyboard}" ]; ++ lib.optionals (cfg.keyboard != null) [ pkgs."${cfg.keyboard}" ];
@@ -204,7 +221,17 @@ in
# TODO: only need the share/sxmo directly linked # TODO: only need the share/sxmo directly linked
"${cfg.package}/share" "${cfg.package}/share"
]; ];
}; } // (lib.filterAttrs # certain settings are read before the `profile` is sourced
(k: v: k == "SXMO_DISABLE_CONFIGVERSION_CHECK")
cfg.settings
);
# sxmo puts in /share/sxmo:
# - profile.d/sxmo_init.sh
# - appcfg/
# - default_hooks/
# - and more
# environment.pathsToLink = [ "/share/sxmo" ];
systemd.services."sxmo-set-permissions" = { systemd.services."sxmo-set-permissions" = {
description = "configure specific /sys and /dev nodes to be writable by sxmo scripts"; description = "configure specific /sys and /dev nodes to be writable by sxmo scripts";
@@ -212,7 +239,7 @@ in
Type = "oneshot"; Type = "oneshot";
ExecStart = "${cfg.package}/bin/sxmo_setpermissions.sh"; ExecStart = "${cfg.package}/bin/sxmo_setpermissions.sh";
}; };
wantedBy = [ "display-manager.service" ]; wantedBy = [ "multi-user.service" ];
}; };
# if superd fails to start a service within 100ms, it'll try to start again # if superd fails to start a service within 100ms, it'll try to start again
@@ -248,18 +275,43 @@ in
}; };
sane.user.fs.".config/sxmo/profile".symlink.text = let sane.user.fs.".config/sxmo/profile".symlink.text = let
mkKeyValue = key: value: ''export ${key}="${value}"''; mkKeyValue = key: value: ''export ${key}="${value}"'';
userConfig = lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings; in
in '' lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings;
# configversion: 4284f96d91e9550ff8f3b25823e402ad
# ^ upstream adds new options every now and then, expects user config file
# to include the md5sum of the template it's based on.
# see `setup_config_version.sh`
${userConfig}
'';
sane.user.fs.".config/sxmo/sway".symlink.target = pkgs.substituteAll { sane.user.fs.".config/sway/config".symlink.target = pkgs.substituteAll {
src = ./sway-config; src = ./sway-config;
waybar = "${pkgs.waybar}/bin/waybar"; waybar = "${pkgs.waybar}/bin/waybar";
bemenu_run = "${pkgs.bemenu}/bin/bemenu-run";
term = "${pkgs.xdg-terminal-exec}/bin/xdg-terminal-exec";
sxmo_init = pkgs.writeShellScript "sxmo_init.sh" ''
# perform the same behavior as sxmo_{x,w}init.sh -- but without actually launching wayland/X11
# this amounts to:
# - setting env vars (e.g. getting the hooks onto PATH)
# - placing default configs in ~ for sxmo-launched services (sxmo_migrate.sh)
# - launching sxmo_hook_start.sh
source ${cfg.package}/etc/profile.d/sxmo_init.sh
# XXX: upstream sources `profile` later (after sxmo_migrate)
# but _sxmo_load_environments uses `SXMO_DEVICE_NAME`,
# and i ship that via the profile, so order it such
source "$XDG_CONFIG_HOME/sxmo/profile"
_sxmo_load_environments
_sxmo_prepare_dirs
sxmo_migrate.sh sync
# kill anything leftover from the previous sxmo run. this way we can (try to) be reentrant
echo "sxmo_init: killing stale daemons (if active)"
sxmo_daemons.sh stop all
pkill bemenu
pkill wvkbd
pkill superd
# configure vol/power-button input mapping (upstream SXMO has this in sway config)
sxmo_swayinitconf.sh
echo "sxmo_init: invoking sxmo_hook_start.sh with:"
echo "PATH: $PATH"
sxmo_hook_start.sh
'';
}; };
sane.user.fs.".config/waybar/config".symlink.target = sane.user.fs.".config/waybar/config".symlink.target =
@@ -279,6 +331,7 @@ in
in pkgs.substituteAll { in pkgs.substituteAll {
src = ./conky-config; src = ./conky-config;
bat = "${battery_estimate}/bin/battery_estimate"; bat = "${battery_estimate}/bin/battery_estimate";
weather = "timeout 20 ${pkgs.sane-weather}/bin/sane-weather";
}; };
} }
@@ -313,32 +366,44 @@ in
}; };
}) })
(lib.mkIf (cfg.greeter == "sway") { (lib.mkIf (cfg.greeter == "greetd-sway-gtkgreet") {
services.greetd = { sane.gui.greetd = {
enable = true; enable = true;
# borrowed from gui/sway sway.enable = true;
settings.default_session.command = sway.gtkgreet.enable = true;
let sway.gtkgreet.session.name = "sxmo-on-gtkgreet";
# start sway and have it construct the gtkgreeter # sway.gtkgreet.session.command = "${cfg.package}/bin/sxmo_winit.sh";
sway-as-greeter = pkgs.writeShellScriptBin "sway-as-greeter" '' sway.gtkgreet.session.command = "${pkgs.sway}/bin/sway --debug";
${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet} > /var/log/sway/sway-as-greeter.log 2>&1
'';
# (config file for the above)
sway-config-into-gtkgreet = pkgs.writeText "greetd-sway-config" ''
exec "${gtkgreet-launcher}"
'';
# gtkgreet which launches a layered sway instance
gtkgreet-launcher = pkgs.writeShellScript "gtkgreet-launcher" ''
# NB: the "command" field here is run in the user's shell.
# so that command must exist on the specific user's path who is logging in. it doesn't need to exist system-wide.
${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command sxmo_winit.sh
'';
in "${sway-as-greeter}/bin/sway-as-greeter";
}; };
})
sane.fs."/var/log/sway" = { (lib.mkIf (cfg.greeter == "greetd-sway-phog") {
dir.acl.mode = "0777"; sane.gui.greetd = {
wantedBeforeBy = [ "greetd.service" "display-manager.service" ]; enable = true;
sway.enable = true;
sway.greeterCmd = "${pkgs.phog}/libexec/phog";
};
# phog locates sxmo_winit.sh via <env>/share/wayland-sessions
environment.pathsToLink = [ "/share/wayland-sessions" ];
})
(lib.mkIf (cfg.greeter == "greetd-phog") {
sane.gui.greetd = {
enable = true;
session.name = "phog";
session.command = "${pkgs.phog}/bin/phog";
};
# phog locates sxmo_winit.sh via <env>/share/wayland-sessions
environment.pathsToLink = [ "/share/wayland-sessions" ];
})
(lib.mkIf (cfg.greeter == "greetd-sxmo") {
sane.gui.greetd = {
enable = true;
session.name = "sxmo";
# session.command = "${cfg.package}/bin/sxmo_winit.sh";
session.command = "${pkgs.sway}/bin/sway --debug";
session.user = "colin";
}; };
}) })
@@ -352,16 +417,6 @@ in
# ''; # '';
# }]; # }];
# services.xserver.enable = true; # services.xserver.enable = true;
# services.greetd = {
# enable = true;
# settings = {
# default_session = {
# command = "${cfg.package}/bin/sxmo_winit.sh";
# user = "colin";
# };
# };
# };
])) ]))
]; ];
} }

View File

@@ -1,10 +1,8 @@
# Default config for sway
# configversion: 5eff902ecca36b4e75567322335cc81c
#
# Copy this to ~/.config/sway/config and edit it to your liking.
#
# Read `man 5 sway` for a complete reference. # Read `man 5 sway` for a complete reference.
# TODO: use stock sxmo config & override via /etc/sway/config.d/*
# especially, this will let me avoid issues around `configversion`
### Variables ### Variables
# #
# Mod4 = Logo key # Mod4 = Logo key
@@ -16,11 +14,13 @@ set $down j
set $up k set $up k
set $right l set $right l
# Your preferred terminal emulator # Your preferred terminal emulator
set $term sxmo_terminal.sh # set $term sxmo_terminal.sh
set $term @term@
# Your preferred application launcher # Your preferred application launcher
# Note: pass the final command to swaymsg so that the resulting window can be opened # Note: pass the final command to swaymsg so that the resulting window can be opened
# on the original workspace that the command was run on. # on the original workspace that the command was run on.
set $menu bemenu-run # N.B. bemenu-run relies on BEMENU_OPTS being set: without this it won't even be visible.
set $menu @bemenu_run@
# xwayland enable|disable|force # xwayland enable|disable|force
# - enable: lazily launch xwayland on first client connection # - enable: lazily launch xwayland on first client connection
@@ -31,7 +31,9 @@ xwayland disable
font "Sxmo 10" font "Sxmo 10"
exec_always sxmo_swayinitconf.sh # configure vol/power-button input maps
# XXX: this references env vars like SXMO_VOLUME_BUTTON => needs to happen after sourcing profile
# exec_always sxmo_swayinitconf.sh
exec_always dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP exec_always dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
@@ -47,25 +49,33 @@ titlebar_border_thickness 1
titlebar_padding 12 1 titlebar_padding 12 1
title_align center title_align center
# tabbed windows by default
workspace_layout tabbed
### tab colors (#border #background #text [#indicator #childBorder]) ### tab colors (#border #background #text [#indicator #childBorder])
# fucused & unfocused are the main interest # focused & unfocused are the main interest
# urgent is used when an inactive window wants attention (e.g. terminal rings a bell)
# colors are synchronized with waybar and mpv
client.focused #1f5e54 #418379 #ffffff client.focused #1f5e54 #418379 #ffffff
client.focused_inactive #1f5e54 #5f676a #ffffff client.focused_inactive #1f5e54 #5f676a #ffffff
client.unfocused #1f5e54 #1f554c #b4b4b4 client.unfocused #1f5e54 #1f554c #b4b4b4
client.urgent #e64291 #e64291 #ffffff client.urgent #ff8080 #ff8080 #ffffff
### Key bindings ### Key bindings
# #
# Basics: # Basics:
# #
input * xkb_options compose:ralt
# Start a terminal # Start a terminal
bindsym $mod+Return exec $term bindsym $mod+Return exec $term
# Launch appmenu # Launch appmenu
bindsym $mod+p exec sxmo_appmenu.sh bindsym $mod+p exec sxmo_appmenu.sh
bindsym $mod+Shift+p exec sxmo_appmenu.sh sys
# Launch scripts menu # Wm menu switcher
bindsym $mod+i exec sxmo_appmenu.sh scripts bindsym $mod+i exec sxmo_wmmenu.sh windowswitcher
# Kill focused window # Kill focused window
bindsym $mod+Shift+q kill bindsym $mod+Shift+q kill
@@ -157,7 +167,7 @@ client.urgent #e64291 #e64291 #ffffff
bindsym $mod+e layout toggle split bindsym $mod+e layout toggle split
# Make the current focus fullscreen # Make the current focus fullscreen
# bindsym $mod+f fullscreen bindsym $mod+f fullscreen
# Toggle the current focus between tiling and floating mode # Toggle the current focus between tiling and floating mode
bindsym $mod+Shift+space floating toggle bindsym $mod+Shift+space floating toggle
@@ -167,6 +177,12 @@ client.urgent #e64291 #e64291 #ffffff
# Move focus to the parent container # Move focus to the parent container
bindsym $mod+a focus parent bindsym $mod+a focus parent
# Manual locker
bindsym $mod+g exec sxmo_hook_locker.sh
# Shutdown
bindsym $mod+t exec sxmo_appmenu.sh power
# #
# Scratchpad: # Scratchpad:
# #
@@ -187,16 +203,16 @@ mode "resize" {
# right will grow the containers width # right will grow the containers width
# up will shrink the containers height # up will shrink the containers height
# down will grow the containers height # down will grow the containers height
bindsym $left resize shrink width 10px bindsym $left resize shrink width 30px
bindsym $down resize grow height 10px bindsym $down resize grow height 30px
bindsym $up resize shrink height 10px bindsym $up resize shrink height 30px
bindsym $right resize grow width 10px bindsym $right resize grow width 30px
# Ditto, with arrow keys # Ditto, with arrow keys
bindsym Left resize shrink width 10px bindsym Left resize shrink width 30px
bindsym Down resize grow height 10px bindsym Down resize grow height 30px
bindsym Up resize shrink height 10px bindsym Up resize shrink height 30px
bindsym Right resize grow width 10px bindsym Right resize grow width 30px
# Return to default mode # Return to default mode
bindsym Return mode "default" bindsym Return mode "default"
@@ -222,15 +238,33 @@ bar {
statusline #ffffff statusline #ffffff
background #323232 background #323232
inactive_workspace #32323200 #32323200 #5c5c5c inactive_workspace #32323200 #32323200 #5c5c5c
font "Sxmo" font "Sxmo 10"
} }
} }
for_window [app_id="pinentry-.*"] floating true
for_window [app_id="foot" title=".*sxmo/modem/.*/draft.txt.*"] resize set height 25 for_window [app_id="foot" title=".*sxmo/modem/.*/draft.txt.*"] resize set height 25
for_window [title="megapixels"] inhibit_idle open for_window [title="megapixels"] inhibit_idle open
# Need playerctl installed and running
bindsym XF86AudioPlay exec playerctl play-pause
bindsym XF86AudioStop exec playerctl stop
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous
bindsym XF86MonBrightnessUp exec sxmo_brightness.sh up
bindsym XF86MonBrightnessDown exec sxmo_brightness.sh down
bindsym Print exec sxmo_screenshot.sh
bindsym button2 kill
bindswitch lid:on exec sxmo_wm.sh dpms on
bindswitch lid:off exec sxmo_wm.sh dpms off
include /etc/sway/config.d/* include /etc/sway/config.d/*
exec 'printf %s "$SWAYSOCK" > "$XDG_RUNTIME_DIR"/sxmo.swaysock' exec 'printf %s "$SWAYSOCK" > "$XDG_RUNTIME_DIR"/sxmo.swaysock'
exec sxmo_hook_start.sh exec_always @sxmo_init@

View File

@@ -24,8 +24,7 @@ in
(mkIf cfg { (mkIf cfg {
sane.programs.docsets.enableFor.system = true; sane.programs.docsets.enableFor.system = true;
sane.programs.ldd-aarch64.enableFor.user.colin = true; sane.programs.ldd-aarch64.enableFor.user.colin = true;
# TODO: migrate this to `sane.user.programs.zeal.enable = true` # sane.programs.zeal.enableFor.user.colin = true;
sane.programs.zeal.enableFor.user.colin = true;
}) })
]; ];
} }

View File

@@ -0,0 +1,21 @@
{
"bozo": 0,
"content_length": 3520653,
"content_type": "application/xml; charset=utf-8",
"description": "There\u2019s a reason the History Channel has produced hundreds of documentaries about Hitler but only a few about Dwight D. Eisenhower. Bad guys (and gals) are eternally fascinating. Behind the Bastards dives in past the Cliffs Notes of the worst humans in history and exposes the bizarre realities of their lives. Listeners will learn about the young adult novels that helped Hitler form his monstrous ideology, the founder of Blackwater\u2019s insane quest to build his own Air Force, the bizarre lives of the sons and daughters of dictators and Saddam Hussein\u2019s side career as a trashy romance novelist.",
"favicon": "",
"favicon_data_uri": "",
"hubs": [],
"is_podcast": true,
"is_push": false,
"item_count": 689,
"last_updated": "2023-08-15T04:00:00+00:00",
"score": 8,
"self_url": "https://www.omnycontent.com/d/playlist/e73c998e-6e60-432f-8610-ae210140c5b1/e5f91208-cc7e-4726-a312-ae280140ad11/d64f756d-6d5e-4fae-b24f-ae280140ad36/podcast.rss",
"site_name": "",
"site_url": "",
"title": "Behind the Bastards",
"url": "https://omnycontent.com/d/playlist/e73c998e-6e60-432f-8610-ae210140c5b1/E5F91208-CC7E-4726-A312-AE280140AD11/D64F756D-6D5E-4FAE-B24F-AE280140AD36/podcast.rss",
"velocity": 0.35,
"version": "rss20"
}

View File

@@ -0,0 +1,21 @@
{
"bozo": 0,
"content_length": 805006,
"content_type": "application/rss+xml; charset=utf-8",
"description": "Wissenschaft und Technik im Kopfhoerer / Science and Engineering in your Headphones",
"favicon": "http://omegataupodcast.net/omegatau_fav.png",
"favicon_data_uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAACC2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjE8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+MjwvdGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KD0UqkwAAB2BJREFUWAmdV1tvVFUU/ubMmQud0k6vUzrTUsq1twSMmKI+idBIJJFECPAACS9NTLzwYkzwof/BoC8QE30xITHSSIgQVEyEUsDUVkRgqC200HtnmPvd9e1hD6cNmOpuTvc+a6+9Lt9ea501tmPHjhXwH4dpmpiamsKePXvQ29urThcKBdhsNqRSKfT19WF8fBzl5eXIZrOKblVBXj6GYcCMRqPWvZIwLihQP1Ymp9OJJ0+eKOFWul7TiFgsBrvdrnieKbQhny/A6XDA5XYrGeKMqayhIu0FaXzP5/PI5XKKroVog2gEPXjeoGLK4JwXT52yRiaFnKBBmeUuD1ZXVWFmdhYGBXNwQx8KhUJ4/PgxpqenEQ6HkUgkkE6nlTfJZFLRL1y4gOehR1lzc3O4desWJh89wq3hYeSEFqnyYcTmxl1HOUYNF/I0LpeH7dChQ2JDAQ6BhbBR6IYNG9Dc3Iza2lp1j/RWI0WvGhsbkclkUFFRgS1btlBnCT0iNjIyogxWCBFZ4U390o9CLAyBDXaHC8OOOlz+MwiTyik8Eomgrq4OBw4cQCAQQFlZmaITcj2IksvlwubNmzWpNGs+Grh169YSXS0EfvxwAkj8KIFVB5S14nb4FXzz+z2YPECIGxoacPDgQdTU1Kh7pzLCrq+IgkjjO73XiDwvDsjHUZDZEOfSiSRs6RQcCaEZcu/2ekQliDEVgknL4/E4enp6FOQ0hkN7pGetiDNpmq6Yl/3TvMKkdvhuFMQICTdFKcRRyGaAcBomoec9NjU1qRzWwukpD2pP6RX3iBhpKxmS7aJQYkDOpau3wXRWSww4YXdXoMzux47dEvj0eP369WCgEXIqoXIq4vudO3cwMTGhgpMBxthgkdm+fbtCjLxWNHjm9OnTWFhYUPGSkfcKrxfhRBOiERamnFxxAe4KJ1o8Lpj0sr6+XjlEYRwUSGXnz5/HuXPnlCLSNP3UqVPo7OzEyZMnVcASHQ07ZQwNDWFwcFBly/z8PDo6OpCX85NT07gZnESDtxId6/w4c+ZnmPSI6aSV0wCm5NjYGC5fvqwOc08HFo1obW3FwMAALl26hKNHj5ZQ00YykDdu3IjKykr1VFdXIytIzEjet3jc8NdXoVz0dnYGiga4pSxSCQXoMStViilHxSyt1j2WYaasLkTcszrALOHVrlq1Ss38HsSkgN2fmGHaIZnJKoQTKQlCMtFjqwCuqcTqtdUAwr3cKG04Z/JqfvJyHQpFpfJJbDnkvcgEQ+gGvWTAWQcNYGqSbjXMykOhL9pbzheNxZFKZ+AwjSVnGHGSUaYKIKswrgmjDiyrwJWuKYMOhMIROJxSVe2G+jAtcVUsEB1FiLRg7RmzQK/13kpnrTyZTCH49xRsRhEt0vnHoaNNVcKVCl4pH51KC+ShyDyyTFFbsaCtckveC+LsB5RzYkzpc7xcOBk49Lx8/9/eGbx/BSeQSWfhcrAnyKsClErJV1HSMSNZQTSowSTUfNGDa3pAS3UW6L2VzDw/vxDG9GIMgUafKJdT8kzNzOL2H9eViGTbS6ivqynqYbBRkdVTrlma/48BPMOo95a7lRNj98bx7jtv4dMTn5TaM5dcRX//9/j6qy9hMp9ZKJiOetAAVsjlhul9PVuN1jQioM4JwS6RD4SkqfGgvb1Ns6j515orajZYsZanHAWvXr16ydUsOS0vvKYXIcQ+oKi8eEo7x+vmx4gjK9WQw2AbxqJDpdZYYD2nAtKYz1TIh3x8Zxn2eDxKiPUcy7rf34gH92eV52RobgoovuLZYiNL1DkMNpksu9bBzTVr1qC7uxtj8lGiMvYN+mGz6vP5sGnTptIxCqfBNHL3rp1Cn8J3315U+907upfw8SX+tPFRPSEFtre3K++0IGbB3r171VdtcnJSNaxUQDj5IWJf6JXvPK9Pf0t4lqOnZzfOnu3H3XtB7HpzJ1rXrVNI6n3KmZ6eEc5y2Pbt21fw+/04cuSIgpZwkpEzvWE2EBHeHwdpOkWJXltbWyle9DmtSB2Qf1omf5QYUhUXFxfxxq63izr48ykYDKouh/dH6/hQCGcGKQ3gu6ZRsb7DmRl6UmxY9Tkq5FrP+lwuV7z3gYFrGLp5RRCsgL2rq6uPHrHtamlpQVVVtSh6JpDCtSAtVNOIBtOYGUPjqUgXNrFBzhW7Y/KTl8E7OjqK3vc+gm9Nk/BKtki71Mc7ZCASCfYHjG4K5H1zjw+N1Gtei14TiRs3bmJOWq/GRr/iozLrQ8PYK167NogPj3+MB5OzqK/1Ii3xYzt8+DCbVnUwGo1JMxlCTW2dtF3r0BTww1vlRZkYZYoR/KgQBQpjZkwL/MHgKC7+dAXjwWG8/8FxvP7aq/AHGuVMsZBFohE8fDiBq1ev4YvPP0NTaxfWBnyIxhOwi6G2/fv3F5LSGsXjKdU0RGIJzMzJb8OHIbmHuIDnRlmtBxVl8vNMIMxIIVmIJJGRDgfyq89d48XmtT4F72/Xh4W2NKWF8HRUY9vLbYKqU1IwqbohbvwDi4As2ZCohrEAAAAASUVORK5CYII=",
"hubs": [],
"is_podcast": true,
"is_push": false,
"item_count": 100,
"last_updated": "2023-06-16T09:08:08+00:00",
"score": 10,
"self_url": "https://omegataupodcast.net/feed/mp3/",
"site_name": "omega tau science & engineering podcast",
"site_url": "https://omegataupodcast.net",
"title": "omega tau science & engineering podcast",
"url": "https://omegataupodcast.net/feed/mp3/",
"velocity": 0.062,
"version": "rss20"
}

View File

@@ -0,0 +1,21 @@
{
"bozo": 0,
"content_length": 87719,
"content_type": "application/xml; charset=utf-8",
"description": "Useful Idiots is an informative and irreverent politics podcast.",
"favicon": "",
"favicon_data_uri": "",
"hubs": [],
"is_podcast": true,
"is_push": false,
"item_count": 20,
"last_updated": "2023-08-15T14:54:32+00:00",
"score": 14,
"self_url": "https://usefulidiots.substack.com/feed",
"site_name": "Useful Idiots | Substack",
"site_url": "https://usefulidiots.substack.com",
"title": "Useful Idiots",
"url": "https://usefulidiots.substack.com/feed",
"velocity": 0.655,
"version": "rss20"
}

View File

@@ -0,0 +1,21 @@
{
"bozo": 0,
"content_length": 232527,
"content_type": "application/xml; charset=utf-8",
"description": "Not wrong political opinions.",
"favicon": "",
"favicon_data_uri": "",
"hubs": [],
"is_podcast": true,
"is_push": false,
"item_count": 67,
"last_updated": "2023-08-09T21:26:55+00:00",
"score": -10,
"self_url": "https://feeds.acast.com/public/shows/6490a2ce7ded6b001126fa5b",
"site_name": "",
"site_url": "",
"title": "We're Not Wrong",
"url": "https://feeds.acast.com/public/shows/6490a2ce7ded6b001126fa5b",
"velocity": 0.145,
"version": "rss20"
}

View File

@@ -9,6 +9,10 @@ let
pname = "ensure-dir"; pname = "ensure-dir";
src = ./.; src = ./.;
}; };
ensure-file = pkgs.static-nix-shell.mkBash {
pname = "ensure-file";
src = ./.;
};
ensure-symlink = pkgs.static-nix-shell.mkBash { ensure-symlink = pkgs.static-nix-shell.mkBash {
pname = "ensure-symlink"; pname = "ensure-symlink";
src = ./.; src = ./.;
@@ -33,6 +37,10 @@ let
type = types.nullOr dirEntry; type = types.nullOr dirEntry;
default = null; default = null;
}; };
file = mkOption {
type = types.nullOr (fileEntryFor name);
default = null;
};
symlink = mkOption { symlink = mkOption {
type = types.nullOr (symlinkEntryFor name); type = types.nullOr (symlinkEntryFor name);
default = null; default = null;
@@ -81,6 +89,8 @@ let
default-acl default-acl
(lib.mkIf (config.dir != null) (lib.mkIf (config.dir != null)
(sane-lib.filterNonNull config.dir.acl)) (sane-lib.filterNonNull config.dir.acl))
(lib.mkIf (config.file != null)
(sane-lib.filterNonNull config.file.acl))
(lib.mkIf (config.symlink != null) (lib.mkIf (config.symlink != null)
(sane-lib.filterNonNull config.symlink.acl)) (sane-lib.filterNonNull config.symlink.acl))
]; ];
@@ -88,6 +98,7 @@ let
# actually generate the item # actually generate the item
generated.command = lib.mkMerge [ generated.command = lib.mkMerge [
(lib.mkIf (config.dir != null) [ "${ensure-dir}/bin/ensure-dir" name ]) (lib.mkIf (config.dir != null) [ "${ensure-dir}/bin/ensure-dir" name ])
(lib.mkIf (config.file != null) [ "${ensure-file}/bin/ensure-file" name config.file.copyFrom ])
(lib.mkIf (config.symlink != null) [ "${ensure-symlink}/bin/ensure-symlink" name config.symlink.target ]) (lib.mkIf (config.symlink != null) [ "${ensure-symlink}/bin/ensure-symlink" name config.symlink.target ])
]; ];
@@ -124,7 +135,27 @@ let
# takes no special options # takes no special options
dirEntry = types.submodule propagatedGenerateMod; dirEntry = types.submodule propagatedGenerateMod;
symlinkEntryFor = path: types.submodule ({ config, ...}: { fileEntryFor = path: types.submodule ({ config, ... }: {
options = {
inherit (propagatedGenerateMod.options) acl;
text = mkOption {
type = types.nullOr types.lines;
default = null;
description = "create a file with this text, overwriting anything that was there before.";
};
copyFrom = mkOption {
type = types.coercedTo types.package toString types.str;
description = "populate the file based on the content at this provided path";
};
};
config = {
copyFrom = lib.mkIf (config.text != null) (
pkgs.writeText (path-lib.leaf path) config.text
);
};
});
symlinkEntryFor = path: types.submodule ({ config, ... }: {
options = { options = {
inherit (propagatedGenerateMod.options) acl; inherit (propagatedGenerateMod.options) acl;
target = mkOption { target = mkOption {

16
modules/fs/ensure-file Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash
set -e
cpto="$1"
cpfrom="$2"
# -f flag in case the destination perms were set to 000
# --no-dereference in case the destination already exists as a symlink
# however, "no-dereference" has the edge case of copying `cpfrom` to `cpto`
# when `cpto` already exists as a symlink to `cpfom`:
# "cp: <cpto> and <cpfrom> are the same file"
# use `--remove-destination` for that
cp --no-dereference -f "$cpfrom" "$cpto" \
|| cp --no-dereference --remove-destination "$cpfrom" "$cpto"

View File

@@ -46,15 +46,15 @@ let
upnpServiceForPort = port: portCfg: upnpServiceForPort = port: portCfg:
lib.mkIf portCfg.visibleTo.wan { lib.mkIf portCfg.visibleTo.wan {
"upnp-forward-${port}" = { "upnp-forward-${port}" = {
description = "forward port ${port} from upstream gateway to this host"; description = "forward port ${port} (${portCfg.description}) from upstream gateway to this host";
restartTriggers = [(builtins.toJSON portCfg)]; restartTriggers = [(builtins.toJSON portCfg)];
serviceConfig.Type = "oneshot"; serviceConfig = {
serviceConfig.TimeoutSec = "6min"; Type = "oneshot";
TimeoutSec = "6min";
after = [ "network.target" ]; Restart = "on-failure";
wantedBy = [ "upnp-forwards.target" ]; RestartSec = "3min";
script = ExecStart =
let let
portFwd = "${pkgs.sane-scripts.ip-port-forward}/bin/sane-ip-port-forward"; portFwd = "${pkgs.sane-scripts.ip-port-forward}/bin/sane-ip-port-forward";
forwards = lib.flatten [ forwards = lib.flatten [
@@ -66,6 +66,10 @@ let
${lib.escapeShellArgs forwards} ${lib.escapeShellArgs forwards}
''; '';
}; };
after = [ "network.target" ];
wantedBy = [ "upnp-forwards.target" ];
};
}; };
in in
{ {

View File

@@ -231,6 +231,7 @@ in
(lib.mapAttrs' (pkgName: _pkg: { name = "cacert.${pkgName}"; value = {}; }) pkgs.cacert) (lib.mapAttrs' (pkgName: _pkg: { name = "cacert.${pkgName}"; value = {}; }) pkgs.cacert)
(lib.mapAttrs' (pkgName: _pkg: { name = "gnome.${pkgName}"; value = {}; }) pkgs.gnome) (lib.mapAttrs' (pkgName: _pkg: { name = "gnome.${pkgName}"; value = {}; }) pkgs.gnome)
(lib.mapAttrs' (pkgName: _pkg: { name = "libsForQt5.${pkgName}"; value = {}; }) pkgs.libsForQt5) (lib.mapAttrs' (pkgName: _pkg: { name = "libsForQt5.${pkgName}"; value = {}; }) pkgs.libsForQt5)
(lib.mapAttrs' (pkgName: _pkg: { name = "mate.${pkgName}"; value = {}; }) pkgs.mate)
(lib.mapAttrs' (pkgName: _pkg: { name = "plasma5Packages.${pkgName}"; value = {}; }) pkgs.plasma5Packages) (lib.mapAttrs' (pkgName: _pkg: { name = "plasma5Packages.${pkgName}"; value = {}; }) pkgs.plasma5Packages)
(lib.mapAttrs' (pkgName: _pkg: { name = "python3Packages.${pkgName}"; value = {}; }) pkgs.python3Packages) (lib.mapAttrs' (pkgName: _pkg: { name = "python3Packages.${pkgName}"; value = {}; }) pkgs.python3Packages)
(lib.mapAttrs' (pkgName: _pkg: { name = "sane-scripts.${pkgName}"; value = {}; }) pkgs.sane-scripts) (lib.mapAttrs' (pkgName: _pkg: { name = "sane-scripts.${pkgName}"; value = {}; }) pkgs.sane-scripts)

View File

@@ -2,6 +2,8 @@
{ {
imports = [ imports = [
./dyn-dns.nix ./dyn-dns.nix
./eg25-control.nix
./eg25-manager.nix
./kiwix-serve.nix ./kiwix-serve.nix
./mautrix-signal.nix ./mautrix-signal.nix
./nixserve.nix ./nixserve.nix

View File

@@ -0,0 +1,27 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.services.eg25-control;
in
{
options.sane.services.eg25-control = with lib; {
enable = mkEnableOption "Quectel EG25 modem configuration scripts. alternative to eg25-manager";
package = mkOption {
type = types.package;
default = pkgs.eg25-control;
};
};
config = lib.mkIf cfg.enable {
systemd.services.eg25-control = {
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/eg25-control --power-on --enable-gps --dump-debug-info --verbose";
Restart = "on-failure";
RestartSec = "60s";
};
after = [ "ModemManager.service" ];
wants = [ "ModemManager.service" ];
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@@ -0,0 +1,69 @@
# eg25-manager: <https://gitlab.com/mobian1/eg25-manager>
# - used by sxmo, in <configs/default_hooks/sxmo_hook_restart_modem_daemons.sh>
# - requires modemmanager (ModemManager.service)
{ config, lib, pkgs, ... }:
let
cfg = config.sane.services.eg25-manager;
eg25-config-toml = pkgs.writeText "eg25-manager-config.toml" ''
# config here is applied *on top of* the per-device configs shipped by eg25-manager.
# these values take precedence, but there's no need to redefine things if we don't want them changed
[at]
uart = "/dev/ttyUSB2"
'';
in
{
options.sane.services.eg25-manager = with lib; {
enable = mkEnableOption "Quectel EG25 modem manager service";
package = mkOption {
type = types.package;
default = pkgs.eg25-manager;
};
};
config = lib.mkIf cfg.enable {
# eg25-manager package ships udev rules *and* a systemd service.
# for that reason, i think it needs to be on the system path for the systemd service to be enabled.
services.udev.packages = [ cfg.package ];
# but actually, let's define our own systemd service so that we can control config
systemd.services.eg25-manager = {
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/eg25-manager --config ${eg25-config-toml}";
ExecStartPre = pkgs.writeShellScript "unload-modem-power" ''
# see issue: <https://gitlab.com/mobian1/eg25-manager/-/issues/38>
${pkgs.kmod}/bin/modprobe -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true
'';
Restart = "on-failure";
RestartSec = "60s"; # can make this more frequent once stable?
# sandboxing (taken from the service file shipped by eg25-manager):
# TODO: this is too strict and breaks access to e.g. /dev/ttyUSB2!
# ProtectControlGroups = true;
# ProtectHome = true;
# ProtectSystem = "strict";
# RestrictSUIDSGID = true;
# PrivateTmp = true;
# MemoryDenyWriteExecute = true;
# PrivateMounts = true;
# NoNewPrivileges = true;
# CapabilityBoundingSet = [ "" ];
# LockPersonality = true;
};
before = [ "ModemManager.service" ];
wantedBy = [ "multi-user.target" ];
};
# systemd.packages = [ pkgs.eg25-manager ];
# systemd.services.eg25-manager.wantedBy = [ "multi-user.target" ];
# systemd.services.prepare-eg25-manager = {
# description = "unload megi's modem_power module to provide gpio access to eg25-manager";
# serviceConfig.Type = "oneshot";
# wantedBy = [ "eg25-manager.service" ];
# before = [ "eg25-manager.service" ];
# script = ''
# ${pkgs.kmod}/bin/modprobe -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true
# '';
# };
};
}

View File

@@ -19,6 +19,19 @@ let
// (if title != null then { name = title; } else {}) // (if title != null then { name = title; } else {})
); );
in [ in [
# (fetchpatch' {
# # disabled, at least until the PR is updated to use `pkg-config` instead of `pkgconfig`.
# # the latter is an alias, which breaks nix-index
# title = "phog: init at 0.1.3";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/251249";
# hash = "sha256-e38Z7sO7xDQHzE9UOfbptc6vJuONE5eP9JFp2Nzx53E=";
# })
(fetchpatch' {
title = "nixos/update-users-groups: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/251850";
hash = "sha256-uqx9sJ1zkwys9Ur35iXY3gZKVb52wlnBGkhBB5sc6WQ=";
})
# (fetchpatch' { # (fetchpatch' {
# # TODO: check back in on this around 2023-10-01 # # TODO: check back in on this around 2023-10-01
@@ -144,12 +157,52 @@ in [
# hash = "sha256-MNG8C0OgdPnFQ8SF2loiEhXJuP2z4n9pkXr8Zh4X7QU="; # hash = "sha256-MNG8C0OgdPnFQ8SF2loiEhXJuP2z4n9pkXr8Zh4X7QU=";
# }) # })
# 2023-08-06: conky wayland + cross compilation patches.
# nix path-info shows clean
# branch is wip-conky-cross2 on servo
# factoring out those feature abstractions was possibly overkill.
# the manual wayland-scanner patching is unfortunate, but within
# acceptable norms of the existing package.
(fetchpatch' { (fetchpatch' {
title = "conky: support wayland"; title = "conky: factor out an abstraction for feature flags";
# saneCommit = "82978099c3a0d5fb4925351da1b0e2598503dc6c"; saneCommit = "3ddf13038d6df90ad0db36a41d55e4077818a3e9";
# hash = "sha256-lnDGEDhmeOIXfFnizEIVUiUzI7nMvpoCERbdjhR+Bto="; hash = "sha256-CjLzndFEH1Ng9CqKX8gxCJ6n/wFv5U/sHnQE0FMYILc=";
saneCommit = "3ad928e20b498444e3a106b182e09317cea9a11f"; })
hash = "sha256-lvIASvQWVFbjHsQwO2EhEBUTSq1UkHvriaZZ2iS0ulU="; (fetchpatch' {
title = "conky: simplify the features even more";
saneCommit = "1c4aa404743f1ae7d5b95f18a96c4057ca251a96";
hash = "sha256-0zhiw9siIkFgFW4sow+X88NBEa3ggCe1t1HJ5xFH4ac=";
})
(fetchpatch' {
title = "conky: support cross compilation";
saneCommit = "01e607e11c7e5bbbfe6ad132fb72394ec29dab0a";
hash = "sha256-Bm/XFLvE7gEyLPlBWNSAcU3qwwqKLIRdpoe0/1aHUho=";
})
(fetchpatch' {
title = "conky: add wayland support";
saneCommit = "84c51f67e02ebc7f118fd3171bd10f1978d4f1e6";
hash = "sha256-gRYbkzCe3q1R7X/FeOcz/haURQkeAfmED1/ZQlCCdWE=";
})
(fetchpatch' {
title = "conky: remove no-op sed patch";
saneCommit = "e8b19984a2858ca24b7e8f5acd20be8b7dfe1af0";
hash = "sha256-K3mG1kcyB7sQZ7ZRCdlinNsV6mCcl3eIUI2ldSmcbJE=";
})
# (fetchpatch' {
# title = "gtk3: compile schemas even when cross compiling";
# saneCommit = "5ee69670071f583bdffe2718dc46763fa1698f92";
# hash = "sha256-ZX3lY63qUW2XuwCoxffbLYoFxckDImKy+S8mqlYJcvk=";
# })
# (fetchpatch' {
# title = "gtk4: compile schemas even when cross compiling";
# saneCommit = "7a1c5e3a5d1ff82c8afa659c7f903d5309d5de6a";
# hash = "sha256-Tz8NBcIqGE9rCqbOrixgbvApYDEAHWCg4lZbklL/xXc=";
# })
(fetchpatch' {
title = "gtk{3,4}: compile schemas even when cross compiling";
prUrl = "https://github.com/NixOS/nixpkgs/pull/247844";
hash = "sha256-1CsjLgMvX0Lx500UDzal5HZi78hb7zBcb+AlNPF6NvA=";
}) })
# (fetchpatch' { # (fetchpatch' {
@@ -171,16 +224,7 @@ in [
# includes hare-json and hare-ev as pre-reqs # includes hare-json and hare-ev as pre-reqs
title = "bonsai: init at 1.0.0"; title = "bonsai: init at 1.0.0";
prUrl = "https://github.com/NixOS/nixpkgs/pull/233892"; prUrl = "https://github.com/NixOS/nixpkgs/pull/233892";
hash = "sha256-f7tdHz0lFsSJO8C0saMuG8e7VzSx8XDy/UXjbqWHP9M="; hash = "sha256-HaTr7GBCfK1I2e7K4k2dUGZ6hZf4PwtEFobLaSz262M=";
})
# make alsa-project members overridable
(fetchpatch' {
title = "alsa-project: expose the scope as a top-level package to support overrides";
prUrl = "https://github.com/NixOS/nixpkgs/pull/246656";
saneCommit = "28f76deae50cc53f5f6a5e846e04426357b8ce2e";
# hash = "sha256-dBWStotLBa4LN7JmriTzoFX3/SQr/qxGO8glv3MNyZQ=";
hash = "sha256-QvurEnupAdPVVnHYl4DC1OqJronGt31REkTJO/alr60=";
}) })
# pin to a pre-0.17.3 release # pin to a pre-0.17.3 release
@@ -200,13 +244,12 @@ in [
hash = "sha256-38sND/UNRj5WAYYKpzdrRBIOK4UAT14RzbIv49KmNNw="; hash = "sha256-38sND/UNRj5WAYYKpzdrRBIOK4UAT14RzbIv49KmNNw=";
}) })
(fetchpatch' { # (fetchpatch' {
# TODO: send this upstream! # title = "mepo: 1.1 -> 1.1.2";
title = "mepo: 1.1 -> 1.1.2"; # prUrl = "https://github.com/NixOS/nixpkgs/pull/247866";
saneCommit = "eee68d7146a6cd985481cdd8bca52ffb204de423"; # saneCommit = "eee68d7146a6cd985481cdd8bca52ffb204de423";
hash = "sha256-uNerTwyFzivTU+o9bEKmNMFceOmy2AKONfKJWI5qkzo="; # hash = "sha256-uNerTwyFzivTU+o9bEKmNMFceOmy2AKONfKJWI5qkzo=";
}) # })
(fetchpatch' { (fetchpatch' {
title = "gthumb: make the webservices feature be optional"; title = "gthumb: make the webservices feature be optional";
@@ -221,23 +264,6 @@ in [
hash = "sha256-rD0es4uUbaLMrI9ZB2HzPmRLyu/ixNBLAFyDJtFHNko="; hash = "sha256-rD0es4uUbaLMrI9ZB2HzPmRLyu/ixNBLAFyDJtFHNko=";
}) })
(fetchpatch' {
title = "p11-kit: build with meson";
prUrl = "https://github.com/NixOS/nixpkgs/pull/244633";
hash = "sha256-+z6hosSyt6ynLpUKS0TsHRoLOS8ck/SK9Y7W2zVUnCQ=";
})
(fetchpatch' {
title = "p11-kit: use mesonEmulatorHook for cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/245124";
hash = "sha256-8NqqLBbjt1fLj4ZYhat7wPqQSv/aez9IwgSK2b4CfW8=";
})
(fetchpatch' {
title = "python310Packages.gssapi: support cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/247048";
saneCommit = "4766ae46f863734fbe96dc4e537870b6b3894cf4";
hash = "sha256-7JZqAlcNFP6orJZCEqe5eodVxTUHeSLGyniRvw/+PuQ=";
})
# (fetchpatch' { # (fetchpatch' {
# title = "perlPackages.FileBaseDir: 0.08 -> 0.09"; # title = "perlPackages.FileBaseDir: 0.08 -> 0.09";
# saneCommit = "acc990b04bbe8c99587eadccc65f100c326ec204"; # saneCommit = "acc990b04bbe8c99587eadccc65f100c326ec204";
@@ -249,10 +275,13 @@ in [
# hash = "sha256-fAZpduh3JZeFixJ4yX0wkh/GRp0gYKsTT+XkNdpK7CU="; # hash = "sha256-fAZpduh3JZeFixJ4yX0wkh/GRp0gYKsTT+XkNdpK7CU=";
# }) # })
(fetchpatch' { (fetchpatch' {
# TODO: split this apart for easier reviewing:
# - perlPackages.TestFile 1.443 -> 1.993
# - perlPackages.FileBaseDir 0.08 -> 0.09
title = "xdg-utils: enable cross compilation"; title = "xdg-utils: enable cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/246954"; prUrl = "https://github.com/NixOS/nixpkgs/pull/246954";
saneCommit = "b7aa5e0c1ec06723cf1594de192703a65be21497"; saneCommit = "b7aa5e0c1ec06723cf1594de192703a65be21497";
hash = "sha256-jA84RKt4nOEZsBlACaqa0GeBiDdFOBYARgAq4NgTqtY="; hash = "sha256-5iYzyjVlye7mhwhlZOHucVod/aPT3OrXolC9jAnB544=";
}) })
# (fetchpatch' { # (fetchpatch' {
# # N.B.: duplicates outstanding, merged PR: <https://github.com/NixOS/nixpkgs/pull/246362> # # N.B.: duplicates outstanding, merged PR: <https://github.com/NixOS/nixpkgs/pull/246362>
@@ -261,69 +290,16 @@ in [
# saneCommit = "4dc30718fe01e9dbed4ffc2ff375148da218e86b"; # saneCommit = "4dc30718fe01e9dbed4ffc2ff375148da218e86b";
# hash = "sha256-Nb2LphSyv8Dayqfwqfua0eKtNzsnaf7PC/KYUhIvnT8="; # hash = "sha256-Nb2LphSyv8Dayqfwqfua0eKtNzsnaf7PC/KYUhIvnT8=";
# }) # })
(fetchpatch' {
title = "gupnp: fix cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/246931";
saneCommit = "3af24c9e517689d048bb62511c6e8acf9bc55684";
# hash = "sha256-6yl6I/zOcUe0TDKEi/vjEzyU4OWoGi0PMht3VOKWmQo=";
hash = "sha256-NYA72+liKZXnUoAGor3MR62YmZNsNPJ3SEfWGhpeiY4=";
})
(fetchpatch' { (fetchpatch' {
title = "blueman: support cross compilation"; title = "blueman: support cross compilation";
saneCommit = "e070195bdf213dffb0164574397b6a7417f81c9e"; saneCommit = "e070195bdf213dffb0164574397b6a7417f81c9e";
hash = "sha256-6JnIJCVBbV4tmFinX7Qv2wO2AThrgxrnyb9T4Ov6p5w="; hash = "sha256-6JnIJCVBbV4tmFinX7Qv2wO2AThrgxrnyb9T4Ov6p5w=";
}) })
# (fetchpatch' {
# # N.B.: duplicates merged PR: <https://github.com/NixOS/nixpkgs/pull/246369>
# title = "tracker: support cross compilation";
# saneCommit = "bea390fd0c4fda96db5b1fad06ee071a10561305";
# hash = "sha256-Y2tVoTvSIIT9ufghqqsXgmqWq9daH+WKj4JHZgWbWwE=";
# })
(fetchpatch' { (fetchpatch' {
title = "tracker-miners: support cross compilation"; title = "tracker-miners: support cross compilation";
saneCommit = "24b062309ea8baa2d8303c0610c9ec7b8c399e8b"; saneCommit = "24b062309ea8baa2d8303c0610c9ec7b8c399e8b";
hash = "sha256-Jj+1z2DeCEY+DqI1J4vYjYJwDDMRcA93CqpZSXzG0wE="; hash = "sha256-Jj+1z2DeCEY+DqI1J4vYjYJwDDMRcA93CqpZSXzG0wE=";
}) })
(fetchpatch' {
# alternate fix for upower; Arturrin
title = "upower: Fix cross";
prUrl = "https://github.com/NixOS/nixpkgs/pull/247031";
hash = "sha256-Skn1dO+SDXbrWYWn8QpSBzYaTis/KUXLEY+pJxO9pWM=";
})
# (fetchpatch' {
# # PR also includes the nativeBuildInputs fix
# title = "upower: fix cross compilation";
# prUrl = "https://github.com/NixOS/nixpkgs/pull/246945";
# saneCommit = "3ab262456acc016c8dc834df1d1f7e61a00e01e3";
# # hash = "sha256-kTFZVu9oDiYH4W4SoQQj0pNuo9hTJk6jUy+hy34HUtA=";
# hash = "sha256-PpC9YRMqg/wPfFgAPNV80mwbZWCKxNi4agxNf0yQutI=";
# })
# (fetchpatch' {
# title = "upower: don't pass unnecessary nativeBuildInputs";
# saneCommit = "e2cbfb1bc81afadc5d31c18d43e774fa9a985f98";
# hash = "sha256-7Q9Fjp7xrw3e887inc5cc01OvuOhThnVYduSLNtv2d0=";
# })
(fetchpatch' {
title = "iio-sensor-proxy: support cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/246947";
saneCommit = "dc1c3341fef6c64d5fbc983670819cf7932f5be1";
# hash = "sha256-lSVGjNepRLMfLgaAG3zv/BfoEhJg8yX7EqaCgu8/b8I=";
hash = "sha256-0rO+qkWgdrZsuHnoRdQ0SqEEW+PYcJaLixrOgJSOssk=";
})
(fetchpatch' {
title = "mpvScripts.mpris: support cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/247087";
saneCommit = "f7cd92e2afa26852ccf53f8ca59c13d82bf7bf64";
# hash = "sha256-MB3qloOW4pXZmbCIVsUKP2DnPoePmBf+qRc2x/o+nDw=";
hash = "sha256-uMbnfO0WY2/AFpvvnHQGKVSTE2rPrm3SCef4f04Bt78=";
})
(fetchpatch' {
title = "wvkbd: support cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/247083";
saneCommit = "34379f5770662b483ab0cbe252cf23dd663d84dc";
# hash = "sha256-Duim5hPBtfGePBte29ZUtojyRAts9lQlbleUsTJNkwI=";
hash = "sha256-aC7zEM4pV4YXh5X0m2nYAkH0vLgVTNq8bgIP8CLZy4I=";
})
(fetchpatch' { (fetchpatch' {
title = "clapper: support cross compilation"; title = "clapper: support cross compilation";
saneCommit = "8a171b49aca406f8220f016e56964b3fae53a3df"; saneCommit = "8a171b49aca406f8220f016e56964b3fae53a3df";
@@ -362,24 +338,33 @@ in [
hash = "sha256-cGhJSby0K+e1hKPdPZjLFRKvwjGaTbq/kb6Fxj2v8g8="; hash = "sha256-cGhJSby0K+e1hKPdPZjLFRKvwjGaTbq/kb6Fxj2v8g8=";
}) })
(fetchpatch' { (fetchpatch' {
# TODO: send for review once thie libgnt patch above is merged
title = "pidgin: support cross compilation"; title = "pidgin: support cross compilation";
saneCommit = "caacbcc54e217f5ee9281422777a7f712765f71a"; saneCommit = "caacbcc54e217f5ee9281422777a7f712765f71a";
hash = "sha256-PDCp4GOm6hWcRob4kz7qXZfxAF6YbYrESx9idoS3e/s="; hash = "sha256-PDCp4GOm6hWcRob4kz7qXZfxAF6YbYrESx9idoS3e/s=";
}) })
(fetchpatch' {
title = "dtrx: 8.5.1 -> 8.5.3";
prUrl = "https://github.com/NixOS/nixpkgs/pull/246282";
saneCommit = "eba9bbc251db942ae27f87824cae643b5f3198c2";
# hash = "sha256-wgpjUXQ/ZnRY5AJ9xOL2BToA7hDaokDiMmPkMt0Y5go=";
hash = "sha256-awUDlibmxcJcdMZeBXcWR1U+P/GCxCH/lalhwZ5Er90=";
})
# (fetchpatch' { # (fetchpatch' {
# title = "dtrx: don't double-wrap the binary"; # # doesn't cleanly apply. TODO: see if this cross compiles now, thanks to <https://github.com/NixOS/nixpkgs/pull/234615>
# saneCommit = "97a9d12b6c31a58e9067eae7cdcd3f53055c124c"; # title = "nixos/dconf: support cross compilation";
# hash = "sha256-g+p96OrBOQAwwH7nwHBuM/KGeIrnBzh9u9lL0M0sYWo="; # prUrl = "https://github.com/NixOS/nixpkgs/pull/249093";
# saneCommit = "08f7cdebc58eeaa62cb349dab57db3be7a0c073d";
# hash = "sha256-gqHUGeTQnr0f99gqEdd+VANLkWO+joLxz5I0RSarznE=";
# }) # })
(fetchpatch' {
title = "playerctl: support cross compilation";
prUrl = "https://github.com/NixOS/nixpkgs/pull/249512";
saneCommit = "67df31a8984ab3067af5b65446d2808b0aedadc6";
hash = "sha256-qY0bjMoFneC5VJ467TeiuOycLYNaVO7Xo/0fCauDZAM=";
})
(fetchpatch' {
title = "libgweather: enable introspection on cross builds";
prUrl = "https://github.com/NixOS/nixpkgs/pull/251956";
saneCommit = "7a2d0a90cc558ea71dfc78356e61b0675b995634";
hash = "sha256-tjO19dXVUrD+V+YpD7z3iWSgNyOirG70HuQ+c+0fZYA=";
})
# (fetchpatch' { # (fetchpatch' {
# # N.B.: compiles, but runtime error on launch suggestive of some module not being shipped # # N.B.: compiles, but runtime error on launch suggestive of some module not being shipped
# title = "matrix-appservice-irc: 0.38.0 -> 1.0.0"; # title = "matrix-appservice-irc: 0.38.0 -> 1.0.0";

File diff suppressed because it is too large Load Diff

View File

@@ -63,6 +63,19 @@ in {
"pyarrow/tests/test_flight.py" "pyarrow/tests/test_flight.py"
]; ];
}); });
# 2023/08/09: unclear why it fails; probably can remove after next nixpkgs update
pillow = py-prev.pillow.overridePythonAttrs (_upstream: {
format = "setuptools";
});
seaborn = py-prev.seaborn.overridePythonAttrs (upstream: {
# 2023/08/09
disabledTestPaths = (upstream.disabledTestPaths or []) ++ [
"tests/test_categorical.py"
"tests/test_core.py"
];
});
}) })
]; ];

View File

@@ -1,27 +1,45 @@
# personal preferences # personal preferences
# prefer to encode these in `sane.programs` # prefer to encode these in `sane.programs`
# resort to this method for e.g. system dependencies, or things which are referenced from too many places. # resort to this method for e.g. system dependencies, or things which are referenced from too many places.
(next: prev: { (self: super: with self; {
pipewire = prev.pipewire.override { gnome = super.gnome.overrideScope' (gself: gsuper: with gself; {
evolution-data-server = gsuper.evolution-data-server.override {
# OAuth depends on webkitgtk_4_1: old, forces an annoying recompilation
enableOAuth2 = false;
gnome-online-accounts = gnome-online-accounts.override {
# avoid webkitgtk_4_1 build
enableBackend = false;
};
};
# gnome-shell = gsuper.gnome-shell.override {
# evolution-data-server-gtk4 = evolution-data-server-gtk4.override {
# # avoid webkitgtk_6_0 build. lol.
# withGtk4 = false;
# };
# };
});
phog = super.phog.override {
# disable squeekboard because it takes 20 minutes to compile when emulated
squeekboard = null;
};
pipewire = super.pipewire.override {
# avoid a dep on python3.10-PyQt5, which has mixed qt5 versions. # avoid a dep on python3.10-PyQt5, which has mixed qt5 versions.
# this means we lose firewire support (oh well..?) # this means we lose firewire support (oh well..?)
ffadoSupport = false; ffadoSupport = false;
}; };
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ pythonPackagesExtensions = super.pythonPackagesExtensions ++ [
(pySelf: pySuper: { (pySelf: pySuper: {
# TODO(2023/08/02): cryptography (a dependency of komikku -> keyring -> secretstorage -> cryptography) doesn't cross compile
# so disable it. can be re-enabled in next staging -> master merge.
# see:
# - <https://github.com/NixOS/nixpkgs/pull/245287/files>
# - <https://github.com/NixOS/nixpkgs/pull/244135>
keyring = (pySuper.keyring.override { keyring = (pySuper.keyring.override {
secretstorage = null; # jaraco-classes doesn't cross compile, but it looks like `keyring`
jeepney = null; # has some _temporary_ fallback logic for when jaraco-classes isn't
# installed (i.e. may break in future).
jaraco-classes = null;
}).overrideAttrs (upstream: { }).overrideAttrs (upstream: {
postPatch = (upstream.postPatch or "") + '' postPatch = (upstream.postPatch or "") + ''
sed -i /SecretStorage/d setup.cfg sed -i /jaraco.classes/d setup.cfg
sed -i /jeepney/d setup.cfg
''; '';
}); });
}) })

View File

@@ -18,6 +18,21 @@ stdenv.mkDerivation rec {
hash = "sha256-jOtFUpl2/Aa7f8JMZf6g63ayFOi+Ci+i7Ac63k63znc="; hash = "sha256-jOtFUpl2/Aa7f8JMZf6g63ayFOi+Ci+i7Ac63k63znc=";
}; };
postPatch = ''
substituteInPlace Makefile \
--replace 'hare build' 'hare build $(HARE_TARGET_FLAGS)'
'';
env.HARE_TARGET_FLAGS =
if stdenv.hostPlatform.isAarch64 then
"-t aarch64"
else if stdenv.hostPlatform.isRiscV64 then
"-t riscv64"
else if stdenv.hostPlatform.isx86_64 then
"-t x86_64"
else
"";
nativeBuildInputs = [ nativeBuildInputs = [
hare hare
hare-ev hare-ev
@@ -31,7 +46,7 @@ stdenv.mkDerivation rec {
# export ARFLAGS="-csr" # export ARFLAGS="-csr"
''; '';
installFlags = [ "PREFIX=" "DESTDIR=$(out)" ]; installFlags = [ "PREFIX=$(out)" ];
passthru.updateScript = gitUpdater { passthru.updateScript = gitUpdater {
rev-prefix = "v"; rev-prefix = "v";

View File

@@ -0,0 +1,6 @@
{ static-nix-shell }:
static-nix-shell.mkPython3Bin {
pname = "eg25-control";
src = ./.;
pkgs = [ "curl" "modemmanager" ];
}

View File

@@ -0,0 +1,429 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ])" -p curl -p modemmanager
# this script should run after ModemManager.service is started.
# typical invocation is `eg25_gps_init.py --enable-power --enable-gps`.
# after running, the user may `cat /dev/ttyUSB1` to view NMEA-encoded GPS information.
# the script attempts to be idempotent, such that it may be run multiple times per boot.
#
# this script downloads assisted GPS (AGPS) data via the system's default gateway (i.e. WiFi)
# and shares that with the modem. this quickens the process of acquiring a GPS fix.
#
# the script may also configure other parts of the modem as `eg25-manager` does.
# these options are less tested: see `--help` for more.
#
# PREREQUISITES/DEPENDENCIES:
# this script expects to run on megi's kernel, with `CONFIG_MODEM_POWER=y`.
# ModemManager must be launched with the `--debug` flag, so that `mmcli --command=...` works.
#
# ModemManager, and by extension this script, REQUIRES A SIM CARD IN YOUR PHONE.
# the sim doesn't need to be "activated". you can buy a $1 SIM and never purchase
# service and that works; it's just needed for ModemManager to boot the modem.
# this isn't a fundamental requirement; if one did everything via serial instead of
# ModemManager the SIM would not be necessary for GPS.
#
# EXPECTATIONS/TIPS:
# - with the right environment, you may get a GPS fix in < 30s.
# - the fix is likely to have a *lot* of jitter, like 10+ meters.
# - indoors, you shouldn't expect to *ever* get a cold-start GPS fix.
# - maybe you'll track 1 satellite if lucky: enough to receive GPS time but not for a GPS fix.
# - get a fix outdoors, then walk indoors: GPS is smart enough to maintain a spotty fix.
# - outdoors in suburbia, a fix might take 10-20 minutes.
# - i have better luck *placing my phone on the roof of my car* than holding it in the air with my hand.
# - maybe a big metal plate opposite the sky acts as a dish/antenna?
# - in Seattle, i track several GLONASS and GPS sats: about an even split.
# - the GPS sats have better SNR.
# - modem seems to not show any BeiDou or Galileo sats even if i enable them.
#
# eg25 modem/GPS docs:
# [GNSS-AP-Note]: https://wiki.pine64.org/images/0/09/Quectel_EC2x%26EG9x%26EG2x-G%26EM05_Series_GNSS_Application_Note_V1.3.pdf
#
# most acronyms are defined inline, particularly near variable/class declarations.
# glossary, for those which aren't:
#
# Global Navigation Satellite Systems (GNSS):
# - GPS (US)
# - GLONASS (RU)
# - Galileo (EU)
# - BeiDou (CN)
# ^ these are all global systems, usable outside the country that owns them
import argparse
import datetime
import logging
import subprocess
import sys
import time
POWER_ENDPOINT = "/sys/class/modem-power/modem-power/device/powered"
# GNSS-AP-Note 1.4:
# also at xtrapath5 and xtrapath6 subdomains.
# the AGPS data here is an almanac good for 7 days.
AGPS_DATA_URI_BASE = "https://xtrapath4.izatcloud.net"
class AgpsDataVariant:
# GNSS-AP-Note 1.4:
gps_glonass = "xtra2.bin"
gps_glonass_beidou = "xtra3grc.bin"
# N.B.: not supported by all Quectel modems
# on stock Pinephone, ModemManager gives "LOC service: general failure"
gps_glonass_beidou_galileo = "xtra3grcej.bin"
logger = logging.getLogger(__name__)
def destructive(fn: callable = None, return_ = None):
""" decorate `fn` so that it becomes a no-op when --dry-run is active """
def wrapped(self, *args, **kwargs):
if self.dry_run:
fmt_args = ", ".join(
[repr(a) for a in args] +
[f"{k}={v}" for k,v in kwargs.items()]
)
logger.info(f"[dry run] {fn.__name__}({fmt_args})")
return return_
else:
return fn(self, *args, **kwargs)
if fn:
return wrapped
else:
return lambda fn: destructive(fn, return_=return_)
def log_scope(at_enter: str, at_exit: str):
""" decorate a function so that it logs at start and end """
def decorator(fn: callable):
def wrapped(*args, **kwargs):
logger.info(at_enter)
ret = fn(*args, **kwargs)
logger.info(at_exit)
return ret
return wrapped
return decorator
class Executor:
def __init__(self, dry_run: bool = False):
self.dry_run = dry_run
@destructive
def write_file(self, path: str, data: bytes) -> None:
logger.debug(f"echo {data!r} > {path}")
with open(path, 'wb') as f:
f.write(data)
@destructive(return_=b'')
def exec(self, cmd: list[str], check: bool = True) -> bytes:
logger.debug(" ".join(cmd))
res = subprocess.run(cmd, capture_output=True)
logger.debug(res.stdout)
if res.stderr:
logger.warning(res.stderr)
if check:
res.check_returncode()
return res.stdout
class GNSSConfig:
# GNSS-AP-Note 2.2.7
# Supported GNSS constellations. GPS is always ON
# 0 GLONASS OFF/BeiDou OFF/Galileo OFF
# 1 GLONASS ON/BeiDou ON/Galileo ON
# 2 GLONASS ON/BeiDou ON/Galileo OFF
# 3 GLONASS ON/BeiDou OFF/Galileo ON
# 4 GLONASS ON/BeiDou OFF/Galileo OFF
# 5 GLONASS OFF/BeiDou ON/Galileo ON
# 6 GLONASS OFF/BeiDou OFF/Galileo ON
# 7 GLONASS OFF/BeiDou ON/Galileo OFF
gps = "0"
gps_glonass_beidou_galileo = "1"
gps_glonass_beidou = "2"
gps_glonass_galilego = "3"
gps_glonass = "4"
gps_beidou_galileo = "5"
gps_galileo = "6"
gps_beidou = "7"
class ODPControl:
# GNSS-AP-Note 2.2.8
# 0 Disable ODP
# 1 Low power mode
# 2 Ready mode
#
# ODP = "On-Demand Positioning"
# Low power mode:
# - low-frequency background GNSS tracking session
# - adjusts interval between 10m (when signal is good) - 60m (when signal is bad)
# Ready mode:
# - 1 Hz positioning
# - keeps GNSS ready so that when application demands position it's immediately ready
# - automatically stops positioning after 60s??
disable = "0"
lower_power_mode = "1"
ready_mode = "2"
class DPOEnable:
# GNSS-AP-Note 2.2.9
# 0 Disable DPO
# 1 Enable the DPO with dynamic duty cycle
#
# DPO = "Dynamic Power Optimization"
# automatically shuts off radio under certain conditions
# more info: <https://sixfab.com/wp-content/uploads/2018/09/Quectel_UC20_GNSS_AT_Commands_Manual_V1.1.pdf> 1.4.1
disable = "0"
enable = "1"
class GPSNMEAType:
# GNSS-AP-Note 2.2.3
# Output type of GPS NMEA sentences in ORed.
disable = 0
gpgga = 1
gprmc = 2
gpgsv = 4
gpgsa = 8
gpvtg = 16
all = 31
class GlonassNmeaType:
# GNSS-AP-Note 2.2.4
# Configure output type of GLONASS NMEA sentences in ORed
disable = 0
glgsv = 1
gngsa = 2
gngns = 4
all = 7
class GalileoNmeaType:
# GNSS-AP-Note 2.2.5
disable = 0
gagsv = 1
all = 1
class BeiDouNmeaType:
# GNSS-AP-Note 2.2.6
disable = 0
pqgsa = 1
pqgsv = 2
all = 3
class AutoGps:
# GNSS-AP-Note 2.2.12
# Enable/disable GNSS to run automatically after the module is powered on.
disable = "0"
enable = "1"
class Sequencer:
AGPS_DATA_URI_BASE = AGPS_DATA_URI_BASE
def __init__(self, executor: Executor, modem: str, power_endpoint: str):
self.executor = executor
self.modem = modem
self.power_endpoint = power_endpoint
def _mmcli(self, args: list[str], check: bool = True) -> str:
return self.executor.exec(
["mmcli", "--modem", self.modem] + args,
check=check
).decode('utf-8')
def _try_mmcli(self, args: list[str]) -> str:
try:
return self._mmcli(args)
except subprocess.CalledProcessError:
return None
def _at_cmd(self, cmd: str, check: bool = True) -> str:
# this returns the mmcli output, which looks like:
# response: 'blah'
# i.e., quoted, and with a `response: ` prefix
return self._mmcli([f"--command=+{cmd}"], check=check)
def _at_structured_cmd(self, cmd: str, subcmd: str | None = None, value: str | None = None, check: bool = True) -> str:
if not subcmd and not value:
return self._at_cmd(cmd, check=check)
elif not subcmd and value:
return self._at_cmd(f"{cmd}={value}", check=check)
elif subcmd and not value:
return self._at_cmd(f"{cmd}=\"{subcmd}\"", check=check)
else:
return self._at_cmd(f"{cmd}=\"{subcmd}\",{value}", check=check)
def _at_gnssconfig(self, cfg: GNSSConfig) -> str:
return self._at_structured_cmd("QGPSCFG", "gnssconfig", cfg)
def _at_odpcontrol(self, control: ODPControl) -> str:
return self._at_structured_cmd("QGPSCFG", "odpcontrol", control)
def _at_dpoenable(self, enable: DPOEnable) -> str:
return self._at_structured_cmd("QGPSCFG", "dpoenable", enable)
def _at_gpsnmeatype(self, ty: GPSNMEAType) -> str:
return self._at_structured_cmd("QGPSCFG", "gpsnmeatype", str(ty))
def _at_glonassnmeatype(self, ty: GlonassNmeaType) -> str:
return self._at_structured_cmd("QGPSCFG", "glonassnmeatype", str(ty))
def _at_galileonmeatype(self, ty: GalileoNmeaType) -> str:
return self._at_structured_cmd("QGPSCFG", "galileonmeatype", str(ty))
def _at_beidounmeatype(self, ty: BeiDouNmeaType) -> str:
self._at_structured_cmd("QGPSCFG", "beidounmeatype", str(ty))
def _at_autogps(self, enable: AutoGps) -> str:
return self._at_structured_cmd("QGPSCFG", "autogps", enable)
def _get_assistance_data(self, variant: AgpsDataVariant) -> str | None:
try:
self.executor.exec(["curl", f"{self.AGPS_DATA_URI_BASE}/{variant}", "-o", variant])
return variant
except subprocess.CalledProcessError as e:
logger.warning(f"AGPS data download failed: {e}")
return None # TODO: could be smarter: return cached AGPS data?
@log_scope("powering modem...", "modem powered")
def power_on(self) -> None:
self.executor.write_file(self.power_endpoint, b'1')
while self._try_mmcli([]) is None:
logger.info("modem hasn't appeared: sleeping for 1s")
time.sleep(1) # wait for modem to appear
def at_check(self) -> None:
""" sanity check that the modem is listening for AT commands and responding reasonably """
hw = self._at_cmd("QGMR")
assert 'EG25GGBR07A08M2G' in hw or self.executor.dry_run, hw
def dump_debug_info(self) -> None:
logger.debug('checking if AGPS is enabled (1) or not (0)')
self._at_structured_cmd('QGPSXTRA?')
# see if the GPS assistance data is still within valid range
logger.debug('QGPSXTRADATA: <valid_duration_minutes>,<start_time_of_agps_data>')
self._at_structured_cmd('QGPSXTRADATA?')
logger.debug('checking what time the modem last synchronized with the network')
self._at_structured_cmd('QLTS')
logger.debug('checking what time the modem thinks it is (extrapolated from sync)')
self._at_structured_cmd('QLTS', value=1)
logger.debug('checking what time the modem thinks it is (from RTC)')
self._at_structured_cmd('CCLK?')
logger.debug('checking if nmea GPS source is enabled')
self._at_structured_cmd('QGPSCFG', 'nmeasrc')
logger.debug('checking if GPS is enabled (1) or not (0)')
self._at_structured_cmd('QGPS?')
logger.debug('checking if GPS has a fix. Error 516 if not')
self._at_structured_cmd('QGPSLOC', value='0', check=False)
logger.debug('dumping AGPS positioning mode bitfield')
self._at_structured_cmd('QGPSCFG', 'agpsposmode')
@log_scope("configuring audio...", "audio configured")
def enable_audio(self) -> None:
# cribbed from eg25-manager; i don't understand these
# QDAI call shouldn't be necessary if using Megi's FW:
# - <https://xnux.eu/devices/feature/modem-pp.html>
self._at_structured_cmd("QDAI", value="1,1,0,1,0,0,1,1")
# RI signaling using physical RI pin
self._at_structured_cmd("QCFG", "risignaltype", "\"physical\"")
# Enable VoLTE support
self._at_structured_cmd("QCFG", "ims", "1")
# Enable APREADY for PP 1.2
self._at_structured_cmd("QCFG", "apready", "1,0,500")
@log_scope("configuring urc...", "urc configured")
def enable_urc(self) -> None:
# cribbed from eg25-manager; i don't even know what URC is
# URC configuration for PP 1.2 (APREADY pin connected):
# * RING URC: normal pulse length
# * Incoming SMS URC: default pulse length
# * Other URC: default length
# * Report URCs on all ports (serial and USB) for FOSS firmware
# * Reporting of URCs without any delay
# * Configure URC pin to UART Ring Indicator
self._at_structured_cmd("QCFG", "urc/ri/ring", "\"pulse\",120,1000,5000,\"off\",1")
self._at_structured_cmd("QCFG", "urc/ri/smsincoming", "\"pulse\",120,1")
self._at_structured_cmd("QCFG", "urc/ri/other", "\"off\",1,1")
self._at_structured_cmd("QCFG", "urc/delay", "0")
self._at_structured_cmd("QCFG", "urc/cache", "0")
self._at_structured_cmd("QCFG", "urc/ri/pin", "uart_ri")
self._at_structured_cmd("QURCCFG", "urcport", "\"all\"")
@log_scope("configuring gps...", "gps configured")
def enable_gps(self) -> None:
# set modem to use UTC time instead of local time.
# modemmanager sends CTZU=3 during init and that causes `AT+CCLK?` to return a timestamp that's off by 600+ days
# see: <https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/360>
self._at_structured_cmd("CTZU", value="1")
# disable GNSS, because it's only configurable while offline
self._at_structured_cmd("QGPSEND", check=False)
# self._at_structured_cmd("QGPS", value="0")
# XXX: ModemManager plugin sets QGPSXTRA=1
# self._at_structured_cmd("QGPSXTRA", value="1")
# now = datetime.datetime.now().strftime('%Y/%m/%d,%H:%M:%S') # UTC
# self._at_structured_cmd("QGPSXTRATIME", value=f"0,\"{now}\"")
locdata = self._get_assistance_data(AgpsDataVariant.gps_glonass_beidou)
if locdata:
self._mmcli([f"--location-inject-assistance-data={locdata}"])
self._at_gnssconfig(GNSSConfig.gps_glonass_beidou_galileo)
self._at_odpcontrol(ODPControl.disable)
self._at_dpoenable(DPOEnable.disable) # N.B.: eg25-manager uses `DPOEnable.enable`
self._at_gpsnmeatype(GPSNMEAType.all)
self._at_glonassnmeatype(GlonassNmeaType.all)
self._at_galileonmeatype(GalileoNmeaType.all)
self._at_beidounmeatype(BeiDouNmeaType.all)
self._at_autogps(AutoGps.disable) #< don't start GPS on modem boot
# configure so GPS output is readable via /dev/ttyUSB1
# self._mmcli(["--location-enable-gps-unmanaged"])
# TODO: tune/document these QGPS values; a smarter setting here might reduce jitter?
self._at_structured_cmd("QGPS", value="1,255,1000,0,1")
@log_scope("configuring powersave...", "powersave configured")
def enable_powersave(self) -> None:
# Allow sleeping for power saving
self._at_structured_cmd("QSCLK", value="1")
# Disable fast poweroff for stability
self._at_structured_cmd("QCFG", "fast/poweroff", "0")
# Configure sleep and wake up pin levels to active low
self._at_structured_cmd("QCFG", "sleepind/level", "0")
self._at_structured_cmd("QCFG", "wakeupin/level", "0,0")
# Do not enter RAMDUMP mode, auto-reset instead
self._at_structured_cmd("QCFG", "ApRstLevel", "1")
self._at_structured_cmd("QCFG", "ModemRstLevel", "1")
def main():
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)
parser = argparse.ArgumentParser(description="initialize the eg25 Pinephone modem for GPS tracking")
parser.add_argument('--modem', default='any', help='name of modem to configure (see mmcli --list-modems)')
parser.add_argument('--power-endpoint', default='/sys/class/modem-power/modem-power/device/powered', help='sysfs endpoint that can turn the modem on/off')
parser.add_argument("--dry-run", action='store_true', help="print commands instead of executing them")
parser.add_argument("--verbose", action='store_true', help="log each command before executing")
parser.add_argument('--power-on', action='store_true', help="enable power to the modem")
parser.add_argument('--enable-audio', action='store_true', help="configure audio for calling (?)")
parser.add_argument('--enable-urc', action='store_true', help="enable support for Unsolicited Return Codes (?)")
parser.add_argument('--enable-gps', action='store_true', help="enable the GPS and acquire tracking until asked to stop")
parser.add_argument('--enable-powersave', action='store_true', help="configure modem to sleep when possible")
parser.add_argument('--dump-debug-info', action='store_true', help="don't initialize anything, just dump debugging data")
args = parser.parse_args()
if args.verbose or args.dump_debug_info:
logging.getLogger().setLevel(logging.DEBUG)
executor = Executor(args.dry_run)
sequencer = Sequencer(executor, modem=args.modem, power_endpoint=args.power_endpoint)
if args.power_on:
sequencer.power_on()
if args.enable_audio:
sequencer.enable_audio()
if args.enable_urc:
sequencer.enable_urc()
if args.enable_gps:
sequencer.enable_gps()
if args.enable_powersave:
sequencer.enable_powersave()
if args.dump_debug_info:
sequencer.dump_debug_info()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,77 @@
# package based on:
# - <https://github.com/NixOS/mobile-nixos/pull/573>
{ lib
, stdenv
, callPackage
, fetchFromGitLab
, gnugrep
, meson
, ninja
, pkg-config
, scdoc
, curl
, glib
, libgudev
, libusb1
# if true, build with MMGLIB. if false, eg25-manager won't speak to modemmanager and will be usable standalone
, withModemManager ? true, modemmanager
}:
let
# eg25-manager needs to be made compatible with libgpiod 2.0 API. see:
# - <https://github.com/NixOS/mobile-nixos/pull/573#issuecomment-1666739462>
# - <https://gitlab.com/mobian1/eg25-manager/-/issues/45>
# nixpkgs libgpiod was bumped 2023-07-29:
# - <https://github.com/NixOS/nixpkgs/pull/246018>
libgpiod1 = callPackage ./libgpiod1.nix { };
in
stdenv.mkDerivation rec {
pname = "eg25-manager";
version = "0.4.6";
src = fetchFromGitLab {
owner = "mobian1";
repo = "eg25-manager";
rev = version;
hash = "sha256-2JsdwK1ZOr7ljNHyuUMzVCpl+HV0C5sA5LAOkmELqag=";
};
postPatch = ''
substituteInPlace 'udev/80-modem-eg25.rules' \
--replace '/bin/grep' '${gnugrep}/bin/grep'
'';
depsBuildBuild = [
pkg-config
];
nativeBuildInputs = [
glib # Contains gdbus-codegen program
meson
ninja
pkg-config
scdoc
];
buildInputs = [
curl
glib
libgpiod1
libgudev
libusb1
] ++ lib.optionals withModemManager [
modemmanager
];
passthru = {
inherit libgpiod1;
};
meta = with lib; {
description = "Manager daemon for the Quectel EG25 mobile broadband modem";
homepage = "https://gitlab.com/mobian1/eg25-manager";
license = licenses.gpl3Plus;
platforms = platforms.linux;
};
}

View File

@@ -0,0 +1,39 @@
{ lib, stdenv, fetchurl, autoreconfHook, autoconf-archive, pkg-config, kmod
, enable-tools ? true
, enablePython ? false, python3, ncurses }:
stdenv.mkDerivation rec {
pname = "libgpiod";
version = "1.6.4";
src = fetchurl {
url = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/snapshot/libgpiod-${version}.tar.gz";
hash = "sha256-gp1KwmjfB4U2CdZ8/H9HbpqnNssqaKYwvpno+tGXvgo=";
};
buildInputs = [ kmod ] ++ lib.optionals enablePython [ python3 ncurses ];
nativeBuildInputs = [
autoconf-archive
pkg-config
autoreconfHook
];
configureFlags = [
"--enable-tools=${if enable-tools then "yes" else "no"}"
"--enable-bindings-cxx"
"--prefix=${placeholder "out"}"
] ++ lib.optional enablePython "--enable-bindings-python";
meta = with lib; {
description = "C library and tools for interacting with the linux GPIO character device";
longDescription = ''
Since linux 4.8 the GPIO sysfs interface is deprecated. User space should use
the character device instead. This library encapsulates the ioctl calls and
data structures behind a straightforward API.
'';
homepage = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about/";
license = licenses.lgpl2;
maintainers = [ maintainers.expipiplus1 ];
platforms = platforms.linux;
};
}

View File

@@ -1,8 +1,8 @@
{ stdenv { stdenv
, fetchFromGitHub , fetchFromGitHub
, fetchFromGitea , fetchFromGitea
, gnused
, mkYarnModules , mkYarnModules
, nodejs
, zip , zip
}: }:
@@ -25,7 +25,8 @@ let
# sha256 = "sha256-dSRZ2ToEOPhzHNvlG8qdewa7689gT8cNB7nXkN3/Avo="; # sha256 = "sha256-dSRZ2ToEOPhzHNvlG8qdewa7689gT8cNB7nXkN3/Avo=";
# }; # };
browserpass-extension-yarn-modules = mkYarnModules { browserpass-extension-yarn-modules = mkYarnModules {
inherit pname version; inherit version;
pname = "${pname}-modules";
packageJSON = ./package.json; packageJSON = ./package.json;
yarnLock = ./yarn.lock; yarnLock = ./yarn.lock;
# yarnNix is auto-generated. to update: leave unset, then query the package deps and copy it out of the store. # yarnNix is auto-generated. to update: leave unset, then query the package deps and copy it out of the store.
@@ -37,9 +38,20 @@ let
in stdenv.mkDerivation { in stdenv.mkDerivation {
inherit pname version src; inherit pname version src;
nativeBuildInputs = [ nodejs zip ];
postPatch = '' postPatch = ''
# dependencies are built separately: skip the yarn install # dependencies are built separately: skip the yarn install
${gnused}/bin/sed -i /yarn\ install/d src/Makefile # prettier, lessc, browserify are made available here via the modules,
# which are for the host (even the devDependencies are compiled for the host).
# but we can just run those via the build node.
#
# alternative would be to patchShebangs in the node_modules dir.
substituteInPlace src/Makefile \
--replace "yarn install" "true" \
--replace ' $(PRETTIER)' ' node $(PRETTIER)' \
--replace ' $(LESSC)' ' node $(LESSC)' \
--replace ' $(BROWSERIFY)' ' node $(BROWSERIFY)'
''; '';
preBuild = '' preBuild = ''
@@ -48,11 +60,12 @@ in stdenv.mkDerivation {
installPhase = '' installPhase = ''
pushd firefox pushd firefox
${zip}/bin/zip -r $out ./* zip -r $out ./*
popd popd
''; '';
passthru = { passthru = {
yarn-modules = browserpass-extension-yarn-modules;
extid = "browserpass@maximbaz.com"; extid = "browserpass@maximbaz.com";
}; };
} }

View File

@@ -20,8 +20,10 @@ stdenv.mkDerivation rec {
./0003-disable-metrics.patch ./0003-disable-metrics.patch
]; ];
nativeBuildInputs = [ zip ];
installPhase = '' installPhase = ''
${zip}/bin/zip -r $out ./* zip -r $out ./*
''; '';
passthru = { passthru = {

View File

@@ -29,7 +29,7 @@ let
}; };
in (stdenv.mkDerivation ({ in (stdenv.mkDerivation ({
# heavily borrows from <repo:nixos/nixpkgs:pkgs/build-support/fetchfirefoxaddon/default.nix> # heavily borrows from <repo:nixos/nixpkgs:pkgs/build-support/fetchfirefoxaddon/default.nix>
inherit (addon) name; name = "${addon.name}-wrapped";
unpackPhase = '' unpackPhase = ''
echo "patching firefox addon $name into $out/${extid}.xpi" echo "patching firefox addon $name into $out/${extid}.xpi"
@@ -64,7 +64,7 @@ let
''; '';
} // args')).overrideAttrs (final: upstream: { } // args')).overrideAttrs (final: upstream: {
passthru = (upstream.passthru or {}) // { passthru = (upstream.passthru or {}) // {
withAttrs = attrs: wrapAddon final.finalPackage attrs; withAttrs = attrs: wrapAddon addon (args // attrs);
withPostPatch = postPatch: final.passthru.withAttrs { inherit postPatch; }; withPostPatch = postPatch: final.passthru.withAttrs { inherit postPatch; };
# given an addon, repackage it without some `perm`ission # given an addon, repackage it without some `perm`ission
withoutPermission = perm: final.passthru.withPostPatch '' withoutPermission = perm: final.passthru.withPostPatch ''
@@ -92,9 +92,9 @@ in lib.makeScope newScope (self: with self; {
ether-metamask = fetchAddon "ether-metamask" "webextension@metamask.io" "sha256-UI83wUUc33OlQYX+olgujeppoo2D2PAUJ+Wma5mH2O0="; ether-metamask = fetchAddon "ether-metamask" "webextension@metamask.io" "sha256-UI83wUUc33OlQYX+olgujeppoo2D2PAUJ+Wma5mH2O0=";
i2p-in-private-browsing = fetchAddon "i2p-in-private-browsing" "i2ppb@eyedeekay.github.io" "sha256-dJcJ3jxeAeAkRvhODeIVrCflvX+S4E0wT/PyYzQBQWs="; i2p-in-private-browsing = fetchAddon "i2p-in-private-browsing" "i2ppb@eyedeekay.github.io" "sha256-dJcJ3jxeAeAkRvhODeIVrCflvX+S4E0wT/PyYzQBQWs=";
sidebery = fetchAddon "sidebery" "{3c078156-979c-498b-8990-85f7987dd929}" "sha256-YONfK/rIjlsrTgRHIt3km07Q7KnpIW89Z9r92ZSCc6w="; sidebery = fetchAddon "sidebery" "{3c078156-979c-498b-8990-85f7987dd929}" "sha256-YONfK/rIjlsrTgRHIt3km07Q7KnpIW89Z9r92ZSCc6w=";
sponsorblock = fetchAddon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-b/OTFmhSEUZ/CYrYCE4rHVMQmY+Y78k8jSGMoR8vsZA="; sponsorblock = fetchAddon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-kIVx/Yl2IZ0/0RqLMf4+HJojoDA7oOUYwZfFvMt/2XE=";
ublacklist = fetchAddon "ublacklist" "@ublacklist" "sha256-NZ2FmgJiYnH7j2Lkn0wOembxaEphmUuUk0Ytmb0rNWo="; ublacklist = fetchAddon "ublacklist" "@ublacklist" "sha256-NZ2FmgJiYnH7j2Lkn0wOembxaEphmUuUk0Ytmb0rNWo=";
ublock-origin = fetchAddon "ublock-origin" "uBlock0@raymondhill.net" "sha256-EGGAA+cLUow/F5luNzFG055rFfd3rEyh8hTaL/23pbM="; ublock-origin = fetchAddon "ublock-origin" "uBlock0@raymondhill.net" "sha256-i3NGi8IzoR3SiVIZRmOBeD0ZEjhX3Qtv0WoBgg/KSDQ=";
# TODO: build bypass-paywalls from source? it's mysteriously disappeared from the Mozilla store. # TODO: build bypass-paywalls from source? it's mysteriously disappeared from the Mozilla store.
# bypass-paywalls-clean = fetchAddon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-oUwdqdAwV3DezaTtOMx7A/s4lzIws+t2f08mwk+324k="; # bypass-paywalls-clean = fetchAddon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-oUwdqdAwV3DezaTtOMx7A/s4lzIws+t2f08mwk+324k=";
@@ -113,7 +113,8 @@ in lib.makeScope newScope (self: with self; {
# XXX: i tried to build sponsorblock from source and patch this *before* it gets webpack'd, # XXX: i tried to build sponsorblock from source and patch this *before* it gets webpack'd,
# but web shit is absolutely cursed and building from source requires a fucking PhD # but web shit is absolutely cursed and building from source requires a fucking PhD
# (if you have one, feel free to share your nix package) # (if you have one, feel free to share your nix package)
${gnused}/bin/sed -i 's/default\.config\.userID)/default.config.userID && false)/' js/background.js substituteInPlace js/background.js \
--replace 'default.config.userId)' 'default.config.userID && false)'
''; '';
ublacklist = wrapAddon unwrapped.ublacklist {}; ublacklist = wrapAddon unwrapped.ublacklist {};

View File

@@ -2,7 +2,7 @@
, fetchFromGitHub , fetchFromGitHub
, libhandy , libhandy
}: }:
gpodder.overrideAttrs (upstream: rec { gpodder.overridePythonAttrs (upstream: rec {
pname = "gpodder-adaptive"; pname = "gpodder-adaptive";
version = "3.11.1+1"; version = "3.11.1+1";
src = fetchFromGitHub { src = fetchFromGitHub {
@@ -12,6 +12,21 @@ gpodder.overrideAttrs (upstream: rec {
hash = "sha256-pn5sh8CLV2Civ26PL3rrkkUdoobu7SIHXmWKCZucBhw="; hash = "sha256-pn5sh8CLV2Civ26PL3rrkkUdoobu7SIHXmWKCZucBhw=";
}; };
# nixpkgs `gpodder` uses the `format = "other"` Makefile build flow.
# upstream specifies a Makefile, and it's just `setup.py` calls plus a few other deps.
# however, it calls the build Python, which breaks for cross compilation.
# nixpkgs knows how to cross-compile setuptools formats, so use that and only mimic the
# parts of the Makefile that aren't part of that.
# TODO: upstream this into main nixpkgs `gpodder` package.
format = "setuptools";
preBuild = ''
make \
"PREFIX=$(out)" \
"share/applications/gpodder-url-handler.desktop" \
"share/applications/gpodder.desktop" \
"share/dbus-1/services/org.gpodder.service"
'';
buildInputs = upstream.buildInputs ++ [ buildInputs = upstream.buildInputs ++ [
libhandy libhandy
]; ];

File diff suppressed because it is too large Load Diff

View File

@@ -13,13 +13,13 @@
rustPlatform.buildRustPackage rec { rustPlatform.buildRustPackage rec {
pname = "lemoa"; pname = "lemoa";
version = "0.3.0"; version = "0.4.0";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "lemmy-gtk"; owner = "lemmy-gtk";
repo = pname; repo = pname;
rev = "v${version}"; rev = "v${version}";
hash = "sha256-LT+UkjDkKbi327SE4VT+BdrpE6hQywajIZ7xpJPvvCc="; hash = "sha256-0xMdshQ12mV93r5UwxRLgYsIj97GgxmDDMEisam29HI=";
}; };
cargoLock = { cargoLock = {

View File

@@ -0,0 +1,37 @@
{ linux_6_4
, fetchpatch
, pkgs
# something inside nixpkgs calls `override` on the kernel and passes in extra arguments; we'll forward them
, ...
}@args:
let
# use the latest commit: for linux 6.4.7
# manjaro's changes between kernel patch versions tend to be minimal if any.
manjaroBase = "https://gitlab.manjaro.org/manjaro-arm/packages/core/linux/-/raw/6c64aa18076a7dc75bfd854b27906467f5d95336";
manjaroPatch = args: {
inherit (args) name;
patch = fetchpatch ({
url = "${manjaroBase}/${args.name}?inline=false";
} // args);
};
# the idea for patching off Manjaro's kernel comes from jakewaksbaum:
# - https://git.sr.ht/~jakewaksbaum/pi/tree/af20aae5653545d6e67a459b59ee3e1ca8a680b0/item/kernel/default.nix
# - he later abandoned this, i think because he's using the Pinephone Pro which received mainline support.
manjaroPatches = [
(manjaroPatch {
# this patch is critical to enable wifi (RTL8723CS)
# - the alternative is a wholly forked kernel by megi/megous:
# - https://xnux.eu/howtos/build-pinephone-kernel.html#toc-how-to-build-megi-s-pinehpone-kernel
# - i don't know if this patch is based on megi's or original.
# - it might be possible to build this rtl8723cs out of tree?
name = "2001-staging-add-rtl8723cs-driver.patch";
hash = "sha256-M4MR9Oi90BmaB68kWjezHon/NzXDxu13Hc+TWm3tcjg=";
})
];
in linux_6_4.override (args // {
kernelPatches = (args.kernelPatches or []) ++ [
pkgs.kernelPatches.bridge_stp_helper
pkgs.kernelPatches.request_key_helper
] ++ manjaroPatches;
})

View File

@@ -1,13 +1,13 @@
{ lib { lib
, buildLinux , buildLinux
, buildPackages , fetchpatch
, fetchFromGitHub , fetchFromGitHub
, modDirVersionArg ? null
, nixosTests
, perl
, pkgs , pkgs
# modem_power is incompatible with eg25-manager: <https://gitlab.com/mobian1/eg25-manager/-/issues/38>
, withModemPower ? true
# something inside nixpkgs calls `override` on the kernel and passes in extra arguments
, ... , ...
} @ args: }@args:
with lib; with lib;
@@ -20,11 +20,11 @@ let
# - orange-pi is listed as the "main integration branch". # - orange-pi is listed as the "main integration branch".
# - this suggests it's NOT a stable branch, only `orange-pi-X.YY-YYYYMMDD-NNNN` tags are "formal" releases # - this suggests it's NOT a stable branch, only `orange-pi-X.YY-YYYYMMDD-NNNN` tags are "formal" releases
# - specific branches like `pp` (pinephone) are dev branches, and probably less stable. # - specific branches like `pp` (pinephone) are dev branches, and probably less stable.
rev = "orange-pi-6.4-20230619-0323"; rev = "orange-pi-6.4-20230731-1920";
hash = "sha256-il32UQM/8Fc7VHft3+M4TLMxk5+h28C9Suu1kRdZj2M="; hash = "sha256-XHYxFvosa1FMOFuyb3OwRc/orcD98fSi9NKf1f+riCA=";
base = "6.4.0"; base = "6.4.7";
# set to empty if not a release candidate, else `-rc<N>` # set to empty if not a release candidate, else `-rc<N>`
rc = "-rc7"; rc = "";
# pinephone uses the linux dtb at arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi # pinephone uses the linux dtb at arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
# - this includes sun50i-a64.dtsi # - this includes sun50i-a64.dtsi
@@ -34,6 +34,18 @@ let
kernelConfig = with lib.kernel; { kernelConfig = with lib.kernel; {
# NB: nix adds the CONFIG_ prefix to each of these. # NB: nix adds the CONFIG_ prefix to each of these.
# if you add the prefix yourself nix will IGNORE YOUR CONFIG. # if you add the prefix yourself nix will IGNORE YOUR CONFIG.
# optimize for faster builds.
# see <repo:kernel.org/linux:Documentation/admin-guide/quickly-build-trimmed-linux.rst>
DEBUG_KERNEL = lib.mkForce no; # option group which seems to just gate the other DEBUG_ opts?
DEBUG_INFO = lib.mkForce no; # for gdb debugging
DEBUG_INFO_BTF = lib.mkForce no; # BPF debug symbols. rec by <https://nixos.wiki/wiki/Linux_kernel#Too_high_ram_usage>
SCHED_DEBUG = lib.mkForce no; # determines /sys/kernel/debug/sched
# SUNRPC_DEBUG = lib.mkForce no; # i use NFS though
MODEM_POWER = lib.mkIf (!withModemPower) no;
# taken from mobile-nixos config?? or upstream megous config??
RTL8723CS = module; RTL8723CS = module;
BT_HCIUART_3WIRE = yes; BT_HCIUART_3WIRE = yes;
BT_HCIUART_RTL = yes; BT_HCIUART_RTL = yes;
@@ -99,35 +111,46 @@ let
extraKernelPatches = [ extraKernelPatches = [
pkgs.kernelPatches.bridge_stp_helper pkgs.kernelPatches.bridge_stp_helper
pkgs.kernelPatches.request_key_helper pkgs.kernelPatches.request_key_helper
(patchDefconfig kernelConfig) # (patchDefconfig kernelConfig)
] ++ lib.optionals (!withModemPower) [
{
# Drop modem-power from DT to allow eg25-manager to have full control.
# source: <https://github.com/NixOS/mobile-nixos/pull/573>
name = "remove-modem-power-from-devicetree";
patch = fetchpatch {
url = "https://gitlab.com/postmarketOS/pmaports/-/raw/164e9f010dcf56642d8e6f422a994b927ae23f38/device/main/linux-postmarketos-allwinner/0007-dts-pinephone-drop-modem-power-node.patch";
sha256 = "nYCoaYj8CuxbgXfy5q43Xb/ebe5DlJ1Px571y1/+lfQ=";
};
}
]; ];
# create a kernelPatch which overrides nixos' defconfig with extra options # create a kernelPatch which overrides nixos' defconfig with extra options
patchDefconfig = config: { # patchDefconfig = config: {
# defconfig options. this method comes from here: # # defconfig options. this method comes from here:
# - https://discourse.nixos.org/t/the-correct-way-to-override-the-latest-kernel-config/533/9 # # - https://discourse.nixos.org/t/the-correct-way-to-override-the-latest-kernel-config/533/9
name = "linux-megous-defconfig"; # name = "linux-megous-defconfig";
patch = null; # patch = null;
extraStructuredConfig = config; # extraStructuredConfig = config;
}; # };
overridenArgs = args // rec { in buildLinux (args // {
version = base + rc; version = base + rc;
# modDirVersion needs to be x.y.z, will automatically add .0 if needed # modDirVersion needs to be x.y.z, where `z` could be `Z-rcN`
modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) + rc else modDirVersionArg; # nix kernel build will sanity check us if we get the modDirVersion wrong
modDirVersion = base + rc;
# branchVersion needs to be x.y # branchVersion needs to be x.y
extraMeta.branch = versions.majorMinor version; extraMeta.branch = versions.majorMinor base;
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "megous"; owner = "megous";
repo = "linux"; repo = "linux";
inherit rev hash; inherit rev hash;
}; };
} // (args.argsOverride or { });
finalArgs = overridenArgs // { kernelPatches = (args.kernelPatches or []) ++ extraKernelPatches;
kernelPatches = overridenArgs.kernelPatches or [] ++ extraKernelPatches;
}; structuredExtraConfig = (args.structuredExtraConfig or {}) // kernelConfig;
in buildLinux finalArgs })

View File

@@ -0,0 +1,55 @@
{ stdenv
, lib
, desktop-file-utils
, fetchFromGitLab
, gettext
, glib
, gobject-introspection
, gtk3
, meson
, ninja
, python3
, wrapGAppsHook
}:
let
# optional deps: avahi, python-keyring
pythonEnv = python3.withPackages (ps: with ps; [ dateutil pygobject3 ]);
in
stdenv.mkDerivation rec {
pname = "mcg";
version = "3.2.1";
src = fetchFromGitLab {
owner = "coderkun";
repo = "mcg";
rev = "v${version}";
hash = "sha256-awPMXGruCB/2nwfDqYlc0Uu9E6VV1AleEZAw9Xdsbt8=";
};
postPatch = ''
substituteInPlace src/meson.build \
--replace "python.find_installation('python3').full_path()" "'${pythonEnv}/bin/python3'"
'';
nativeBuildInputs = [
gtk3 # for gtk-update-icon-cache
desktop-file-utils # for update-desktop-database
gettext # for msgfmt
glib # for glib-compile-resources
gobject-introspection # needed so wrapGAppsHook includes GI_TYPEPATHS for gtk3
meson
ninja
wrapGAppsHook
];
buildInputs = [
gtk3
];
meta = with lib; {
description = "CoverGrid (mcg) is a client for the Music Player Daemon (MPD), focusing on albums instead of single tracks.";
homepage = "https://www.suruatoel.xyz/codes/mcg";
platforms = platforms.linux;
# license = TODO
maintainers = with maintainers; [ colinsane ];
};
}

View File

@@ -4,7 +4,7 @@
, mpvScripts , mpvScripts
}: }:
mpvScripts.uosc.overrideAttrs (upstream: { mpvScripts.uosc.overrideAttrs (upstream: {
version = "unstable-2023-07-26"; version = "unstable-2023-08-29";
# src = fetchFromGitHub { # src = fetchFromGitHub {
# owner = "tomasklaen"; # owner = "tomasklaen";
# repo = "uosc"; # repo = "uosc";
@@ -15,8 +15,8 @@ mpvScripts.uosc.overrideAttrs (upstream: {
domain = "git.uninsane.org"; domain = "git.uninsane.org";
owner = "colin"; owner = "colin";
repo = "uosc"; repo = "uosc";
rev = "dev/sane"; rev = "sane-0.2";
hash = "sha256-XOhryppod3zozYrPQlGBw298u+0/eS1MaDepV4p88cM="; hash = "sha256-j5hX+lAf7mHx4vqI0shOekmOh4aZsOiRb3rPs8vQ4qo=";
# for version > 4.7.0, we can use nixpkgs src and set `patches` to a fetch of my one custom commit # for version > 4.7.0, we can use nixpkgs src and set `patches` to a fetch of my one custom commit
}; };
passthru = upstream.passthru // { passthru = upstream.passthru // {

View File

@@ -0,0 +1,102 @@
{ lib
, stdenv
, fetchFromGitLab
, meson
, ninja
, pkg-config
, gcr
, glib
, gnome-desktop
, gtk3
, libgudev
, libjson
, json-glib
, libhandy
, networkmanager
, linux-pam
, systemd
, upower
, wayland
, libxkbcommon
, python3
, phoc
, bash
, gnome
, squeekboard ? null
, wayland-scanner
, wrapGAppsHook
}:
stdenv.mkDerivation rec {
pname = "phog";
version = "0.1.3";
src = fetchFromGitLab {
owner = "mobian1";
repo = "phog";
rev = version;
hash = "sha256-zny1FUYKwVXVSBGTh8AFVtMBS7dWZHTKO2gkPNPSL2M=";
};
patches = [
./sway-compat.patch
];
postPatch = ''
patchShebangs build-aux/post_install.py
sed -i /phog_plugins_dir/d build-aux/post_install.py
substituteInPlace src/greetd.c \
--replace '/usr/share/wayland-sessions' '/run/current-system/sw/share/wayland-sessions/' \
--replace '/usr/share/xsessions' '/run/current-system/sw/share/xsessions'
'' + lib.optionalString (squeekboard == null) ''
substituteInPlace data/phog.in \
--replace " & squeekboard" ""
'';
preFixup = ''
gappsWrapperArgs+=(
--prefix PATH : ${lib.makeBinPath [ bash squeekboard ]}
--prefix XDG_DATA_DIRS : "${gnome.gnome-shell}/share/gsettings-schemas/${gnome.gnome-shell.name}"
)
'';
mesonFlags = [ "-Dcompositor=${phoc}/bin/phoc" ];
depsBuildBuild = [
pkg-config
];
buildInputs = [
gcr
glib
gnome-desktop
gtk3
libgudev
libjson
json-glib
libhandy
networkmanager
linux-pam
systemd
upower
wayland
libxkbcommon
];
nativeBuildInputs = [
meson
ninja
pkg-config
python3
glib
wayland-scanner
wrapGAppsHook
];
meta = with lib; {
description = "Greetd-compatible greeter for mobile phones";
homepage = "https://gitlab.com/mobian1/phog/";
license = licenses.gpl3Only;
maintainers = with maintainers; [ matthewcroughan ];
};
}

View File

@@ -0,0 +1,31 @@
commit 86593b754405a194e749e424e27710aa08533853
Author: Colin <colin@uninsane.org>
Date: 2023-08-26 12:26:36 +0000
make phoc-specific wayland interface optional: zphoc_layer_shell_effects_v1
diff --git a/src/drag-surface.c b/src/drag-surface.c
index 0e1a371f..56f7a307 100644
--- a/src/drag-surface.c
+++ b/src/drag-surface.c
@@ -204,6 +204,7 @@ phog_drag_surface_configured (PhogLayerSurface *layer_surface)
return;
/* Configure drag surface if not done yet */
+ g_return_if_fail(priv->layer_shell_effects);
priv->drag_surface = zphoc_layer_shell_effects_v1_get_draggable_layer_surface (priv->layer_shell_effects,
wl_layer_surface);
zphoc_draggable_layer_surface_v1_add_listener (priv->drag_surface, &drag_surface_listener, self);
diff --git a/src/phog-wayland.c b/src/phog-wayland.c
index 99933116..7c2d76ad 100644
--- a/src/phog-wayland.c
+++ b/src/phog-wayland.c
@@ -274,7 +274,7 @@ phog_wayland_constructed (GObject *object)
!self->input_inhibit_manager || !self->xdg_wm_base ||
!self->zxdg_output_manager_v1 ||
!self->zphoc_layer_shell_effects_v1) {
- g_error ("Wayland compositor lacks needed globals\n"
+ g_warning ("Wayland compositor lacks needed globals\n"
"outputs: %d, layer_shell: %p, idle_manager: %p, "
"inhibit: %p, xdg_wm: %p, "
"xdg_output: %p, wlr_output_manager: %p, "

View File

@@ -191,6 +191,12 @@ let
src = ./src; src = ./src;
pkgs = [ "rsync" ]; pkgs = [ "rsync" ];
}; };
sync-music = static-nix-shell.mkPython3Bin {
pname = "sane-sync-music";
src = ./src;
pkgs = [ "ffmpeg" "sox" ];
pyPkgs = [ "unidecode" ];
};
vpn-down = static-nix-shell.mkBash { vpn-down = static-nix-shell.mkBash {
pname = "sane-vpn-down"; pname = "sane-vpn-down";
src = ./src; src = ./src;

View File

@@ -23,9 +23,13 @@ options:
# - Torznab: <https://torznab.github.io/spec-1.3-draft/index.html> # - Torznab: <https://torznab.github.io/spec-1.3-draft/index.html>
# - TorrentPotato: <https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider> # - TorrentPotato: <https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider>
# - its own JSON-based API # - its own JSON-based API
#
# about torrent jargon:
# - <https://en.wikipedia.org/wiki/Pirated_movie_release_types>
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
import argparse
import logging import logging
import json import json
import natsort import natsort
@@ -66,9 +70,31 @@ def parse_time(t: str) -> datetime:
return try_parse_time(t).astimezone() or epoch return try_parse_time(t).astimezone() or epoch
# preference, best to worst
TRACKER_RANKS = [
'bakabt',
'nyaa.si',
'yts',
'internet archive',
'the pirate bay',
# haven't sorted these
'1337x',
'kickasstorrents.to',
]
def tracker_rank(tracker: str):
if tracker.lower() in TRACKER_RANKS:
return TRACKER_RANKS.index(tracker.lower())
logger.warn(f"unknown tracker: {tracker!r}")
return len(TRACKER_RANKS)
DROP_CATS = { "dvd", "hd", "misc", "other", "sd", "uhd" } DROP_CATS = { "dvd", "hd", "misc", "other", "sd", "uhd" }
MANGA_CATS = { "books", "comics", "ebook" } MANGA_CATS = { "books", "comics", "ebook" }
KNOWN_CATS = frozenset(list(MANGA_CATS) + ["anime", "audio", "movies", "tv", "xxx"]) VIDEO_CATS = { "anime", "movies", "tv" }
KNOWN_CATS = frozenset(
list(MANGA_CATS) +
list(VIDEO_CATS) +
["audio", "xxx"]
)
def clean_cat(c: str) -> str | None: def clean_cat(c: str) -> str | None:
if c in DROP_CATS: return None if c in DROP_CATS: return None
return c return c
@@ -83,6 +109,38 @@ def is_cat(cats: list[str], wanted_cats: list[str], default: bool = False) -> bo
else: else:
return any(c in wanted_cats for c in cats) return any(c in wanted_cats for c in cats)
class Filter:
def __init__(self, h265: bool=False, manga: bool=False, video: bool=False):
self.h265 = h265
self.manga = manga
self.video = video
def filter(self, torrents: list['Torrent']) -> list['Torrent']:
return [t for t in torrents if self.is_match(t)]
def is_match(self, t: 'Torrent', default: bool = False) -> bool:
valid = True
valid = valid and (not self.h265 or self.is_h265(t))
valid = valid and (not self.manga or self.is_manga(t, default))
valid = valid and (not self.video or self.is_video(t, default))
return valid
@staticmethod
def is_h265(t: 'Torrent') -> bool:
meta = t.title.lower()
return "h265" in meta \
or "x265" in meta \
or "HEVC" in meta
@staticmethod
def is_manga(t: 'Torrent', default: bool = False) -> bool:
return is_cat(t.categories, MANGA_CATS, default)
@staticmethod
def is_video(t: 'Torrent', default: bool = False) -> bool:
return is_cat(t.categories, VIDEO_CATS, default)
@dataclass(eq=True, order=True, unsafe_hash=True) @dataclass(eq=True, order=True, unsafe_hash=True)
class Torrent: class Torrent:
seeders: int seeders: int
@@ -151,15 +209,6 @@ class Torrent:
magnet=self.magnet, magnet=self.magnet,
) )
def is_manga(self, default: bool = False) -> bool:
return is_cat(self.categories, MANGA_CATS, default)
def is_h265(self) -> bool:
meta = self.title.lower()
return "h265" in meta \
or "x265" in meta \
or "HEVC" in meta
class Client: class Client:
def __init__(self): def __init__(self):
self.apikey = open("/run/secrets/jackett_apikey").read().strip() self.apikey = open("/run/secrets/jackett_apikey").read().strip()
@@ -182,80 +231,55 @@ class Client:
return sorted(torrents, reverse=True) return sorted(torrents, reverse=True)
def sort_results(torrents: list[Torrent], by: str) -> list[Torrent]:
if by == 'seeders':
return sorted(torrents, key=lambda t: (t.seeders, t), reverse=True)
elif by == 'tracker':
return sorted(torrents, key=lambda t: (-tracker_rank(t.tracker), t), reverse=True)
assert False, f"unknown sort method: {by}"
def filter_results(results: list[Torrent], full: bool, top: int, manga: bool, h265: bool) -> list[Torrent]: def format_results(all_results: list[Torrent], filtered_results: list[Torrent], json: bool):
""" if json:
take the complete query and filter further based on CLI options dumpable = [t.to_dict() for t in filtered_results]
""" print(json.dumps(dumpable))
if manga:
results = [t for t in results if t.is_manga(default=True)]
if h265:
results = [t for t in results if t.is_h265()]
if not full:
results = results[:top]
return results
def parse_args(args: list[str]) -> dict:
options = dict(
full=False,
help=False,
json=False,
query="",
top="5",
verbose=False,
manga=False,
h265=False,
)
while args:
arg = args[0]
del args[0]
if arg.startswith('--'):
opt = arg[2:]
if "=" in opt:
name, val = opt.split('=')
else: else:
name, val = opt, True num_total = len(all_results)
options[name] = val num_filtered = len(filtered_results)
else: print(f"found {num_total} result(s) filtered to {num_filtered}")
options["query"] = options["query"] + " " + arg if options["query"] else arg for r in filtered_results:
print(r)
return options
def main(args: list[str]): def main(args: list[str]):
logging.basicConfig() logging.basicConfig()
options = parse_args(args) logging.getLogger().setLevel(logging.WARNING)
full = options.pop("full")
help = options.pop("help")
json = options.pop("json")
query = options.pop("query")
assert options.get("top") is not True, "use `--top=N`, not `--top N`"
top = int(options.pop("top"))
verbose = options.pop("verbose")
manga = options.pop("manga")
h265 = options.pop("h265")
if options != {}: parser = argparse.ArgumentParser(description='search torrent trackers')
raise BadCliArgs(f"unexpected options: {options}") parser.add_argument('--full', action='store_true', help='show all results')
if help: parser.add_argument('--top', help='how many results to show (default: 5)')
raise BadCliArgs() parser.add_argument('--sort-by', default='seeders', help='how to rank matches (seeders, tracker)')
parser.add_argument('--json', action='store_true', help='output results in json')
parser.add_argument('--verbose', action='store_true')
parser.add_argument('--h265', action='store_true', help='show only H.265/HEVC results (might cause false negatives)')
parser.add_argument('--manga', action='store_true', help='show only manga results')
parser.add_argument('--video', action='store_true', help='show only video (tv or film)')
parser.add_argument("query", help="text to search for in torrent titles/descriptions")
if verbose: args = parser.parse_args()
if args.verbose:
logging.getLogger().setLevel(logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG)
client = Client() client = Client()
results = client.query(query) all_results = client.query(args.query)
num_results = len(results)
results = filter_results(results, full, top, manga, h265) filter = Filter(h265=args.h265, manga=args.manga, video=args.video)
filtered_results = filter.filter(all_results)
ordered_results = sort_results(filtered_results, args.sort_by)
if json: if not args.full:
dumpable = [t.to_dict() for t in results] ordered_results = ordered_results[:int(args.top or "5")]
print(json.dumps(dumpable))
else: format_results(all_results, ordered_results, args.json)
print(f"found {num_results} result(s)")
for r in results:
print(r)
if __name__ == "__main__": if __name__ == "__main__":
main(sys.argv[1:]) main(sys.argv[1:])

View File

@@ -1,11 +1,13 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i bash -p systemd #!nix-shell -i bash -p systemd
sudo systemctl stop matrix-appservice-irc mx-puppet-discord sudo systemctl stop matrix-appservice-irc mx-puppet-discord mautrix-signal signald
sudo systemctl stop pleroma gitea matrix-synapse jellyfin transmission jackett sudo systemctl stop ejabberd gitea lemmy-ui matrix-synapse pict-rs pleroma
sudo systemctl stop ejabberd goaccess i2p kiwix-serve navidrome sudo systemctl stop dovecot2 opendkin postfix
sudo systemctl stop i2p jackett transmission
sudo systemctl stop jellyfin kiwix-serve komga navidrome
sudo systemctl stop goaccess
# TODO: stop the freshrss timer # TODO: stop the freshrss timer
sudo systemctl stop phpfpm-freshrss sudo systemctl stop phpfpm-freshrss
sudo systemctl stop dovecot2 opendkin postfix
sudo systemctl stop nginx sudo systemctl stop nginx
sudo systemctl stop postgresql sudo systemctl stop postgresql
sudo systemctl stop duplicity.timer sudo systemctl stop duplicity.timer

View File

@@ -0,0 +1,204 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ps.unidecode ])" -p ffmpeg -p sox
# vim: set filetype=python :
import argparse
import concurrent.futures
import logging
import multiprocessing
import os
import subprocess
from pathlib import Path
from unidecode import unidecode
logger = logging.getLogger(__name__)
MAKE_MP3 = [
'.flac',
'.oga',
'.ogg',
'.opus',
'.wav',
'.wma',
]
COPY_RAW = [
'.aac',
'.bmp',
'.gif',
'.jpeg',
'.jpg',
'.m4a',
'.mp3',
'.png',
]
IGNORE = [
'.DS_Store',
'.avi',
'.cue',
'.inf',
'.log',
'.lyrics',
'.m3u',
'.mov',
'.mp4',
'.nsf_',
'.pdf',
'.toc',
'.txt',
'.webm',
]
class Encoder:
def __init__(self, dry_run: bool = False):
self.dry_run = dry_run
def check_output_no_sideeffect(self, args: list[str]) -> bytes:
return subprocess.check_output(args)
def check_output(self, args: list[str]) -> str:
if self.dry_run:
logger.debug("not invoking because dry run: " + ' '.join(args))
return b""
else:
return subprocess.check_output(args)
def cp(self, source: Path, dest: Path) -> None:
self.check_output(['cp', str(source), str(dest)])
def ensure_dir(self, dir: Path) -> None:
if self.dry_run:
logger.debug(f"not invoking because dry run: os.makedirs({dir!r}, exist_ok=True)")
else:
os.makedirs(str(dir), exist_ok=True)
def remove(self, path: Path) -> None:
if self.dry_run:
logger.debug(f"not invoking because dry run: os.remove({path!r})")
else:
os.remove(path)
def convert(self, source: Path, dest: Path) -> None:
source_samplerate = None
try:
source_samplerate = int(self.check_output_no_sideeffect(['soxi', '-r', str(source)]).decode("utf-8").strip())
except:
if str(source).endswith('.wma'):
logging.debug(f'unsupported extension for samplerate: {source}')
else:
logging.warning(f'unable to obtain samplerate for {source}')
samplerate_map = {
192000: 48000,
96000: 48000,
88200: 44100,
# preserve as-is
48000: 48000,
44100: 44100,
}
target_samplerate = samplerate_map.get(source_samplerate)
if source_samplerate and not target_samplerate:
logging.warning(f'unable to map source sample rate: {source_samplerate}')
samplerate_flags = ['-ar', str(target_samplerate)] if target_samplerate else []
self.check_output([
'ffmpeg',
'-i', str(source),
'-codec:v', 'copy',
'-codec:a', 'libmp3lame',
'-qscale:a', '0'
] + samplerate_flags + [str(dest)])
def clean_name(path: str) -> Path:
'''
transform a path into something which most filesystems/protocols can reliably support
'''
out_path = Path()
for part in path.parts:
blacklisted = '"\'!@#$%^&*()[]{};:,<>?`~|\\/'
part = unidecode(part)
part = ''.join(c for c in part if c not in blacklisted)
out_path /= part
return out_path
def target_name(source_name: str) -> Path:
n = clean_name(source_name)
if n.suffix in MAKE_MP3:
return Path(str(n) + '.mp3')
else:
return n
def calculate_delta(in_dir: str, out_dir: str) -> tuple[set[Path], set[Path]]:
'''
Returns the set of dest files which need to be deleted, followed by the files to copy
'''
in_files = { p.relative_to(in_dir) for p in Path(in_dir).rglob("*") if not p.is_dir() }
logger.info(f'found {len(in_files)} files in source')
existing_out_files = { p.relative_to(out_dir) for p in Path(out_dir).rglob("*") if not p.is_dir() }
logger.info(f'found {len(existing_out_files)} files in dest')
expected_out_files = { target_name(n) for n in in_files }
to_del = { f for f in existing_out_files if f not in expected_out_files }
logger.info(f'found {len(to_del)} files to delete')
to_copy = { f for f in in_files if target_name(f) not in existing_out_files and f.suffix not in IGNORE }
logger.info(f'found {len(to_copy)} files to copy')
return to_del, to_copy
def rm_dest_files(encoder: Encoder, out_dir: str, files: set[Path]) -> None:
for f in files:
logger.info(f'removing {f} because it does not exist on host')
encoder.remove(Path(out_dir) / f)
def copy_one(encoder: Encoder, source: Path, dest: Path) -> None:
encoder.ensure_dir(dest.parent)
if source.suffix in MAKE_MP3:
logger.debug(f'converting {source} -> {dest}')
encoder.convert(source, dest)
elif source.suffix in COPY_RAW:
logger.debug(f'copying {source} -> {dest}')
encoder.cp(source, dest)
else:
logger.warning(f"skipping {source} because I don't know what to do with that file type")
def cp_src_files(encoder: Encoder, in_dir: Path, out_dir: Path, src_names: set[Path], jobs: int):
logger.info(f'using {jobs} jobs to copy {len(src_names)} files')
# Parallel(n_jobs=jobs)(delayed(copy_one)(encoder, in_dir / n, out_dir / target_name(n)) for n in src_names)
with concurrent.futures.ThreadPoolExecutor(max_workers=jobs) as executor:
for n in src_names:
executor.submit(copy_one, encoder, in_dir / n, out_dir / target_name(n))
def sync_all(in_dir: str, out_dir: str, jobs: int = None, dry_run: bool = False) -> None:
encoder = Encoder(dry_run=dry_run)
to_del, to_copy = calculate_delta(in_dir, out_dir)
rm_dest_files(encoder, out_dir, to_del)
cp_src_files(encoder, in_dir, out_dir, to_copy, jobs = jobs or multiprocessing.cpu_count())
def main() -> None:
logging.basicConfig()
logger.setLevel(logging.INFO)
parser = argparse.ArgumentParser(description="synchronize music from one directory to another, possibly compressing it")
parser.add_argument("src", help="source directory")
parser.add_argument("dest", help="destination directory")
parser.add_argument("--jobs", help="number of cores to compress music with (default: all CPU cores)", default=None, type=int)
parser.add_argument("--dry-run", action='store_true', help="don't actually run any commands")
parser.add_argument("--verbose", action='store_true', help="more logging")
parser.add_argument("--quiet", action='store_true', help="less logging")
args = parser.parse_args()
if args.verbose:
logger.setLevel(logging.DEBUG)
if args.quiet:
logger.setLevel(logging.WARN)
sync_all(args.src, args.dest, args.jobs, args.dry_run)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,36 @@
{ stdenv
, glib-networking
, gobject-introspection
, libgweather
, python3
, wrapGAppsNoGuiHook
}:
let
pyEnv = python3.withPackages (ps: [
ps.pygobject3
]);
in
stdenv.mkDerivation {
pname = "sane-weather";
version = "0.1";
src = ./.;
nativeBuildInputs = [
gobject-introspection
wrapGAppsNoGuiHook
];
buildInputs = [
glib-networking
libgweather
pyEnv
];
installPhase = ''
runHook preInstall
mkdir -p "$out/bin"
cp sane-weather "$out/bin"
runHook postInstall
'';
}

View File

@@ -0,0 +1,195 @@
#!/usr/bin/env python3
# to get GWeather logging, run with
# `G_MESSAGES_DEBUG=GWeather`
# queries weather from public (gov) sources and renders it to stdout.
# primary consumer is conky.
# very limited; libgweather is a little iffy and doesn't expose everything the raw APIs do
# e.g. no precise precipitation predictions.
#
# future work:
# - consider using python-native pynws: <https://github.com/MatthewFlamm/pynws>
# - it's well-factored, exposing a nice interface but letting me dig as deep as i want wherever that's incomplete.
# - render a graph with rain + temperature forecast
# - conky supports graphs with [execgraph](https://conky.cc/variables#execgraph)
import argparse
import code
import gi
import logging
import time
gi.require_version('GWeather', '4.0')
from gi.repository import GLib
from gi.repository import GWeather
logger = logging.getLogger(__name__)
class WeatherSource:
'''
this class abstracts operations which would query a remote weather server
'''
def __init__(self):
self.info = GWeather.Info()
self.info.set_application_id('org.uninsane.sane-weather')
self.info.set_contact_info('contact@uninsane.org')
self.info.set_enabled_providers(
# defaults to METAR | IWIN.
# options are:
# - IWIN # graphical.weather.gov; provides daily min/max temp, precipitation
# - METAR # aviationweather.gov; provides current time, wind, visibility, conditions, clouds, temperature, pressure
# - MET_NO
# - NWS # api.weather.gov; provides hourly temperature, dewpoint, humidity, sky cover, wind, precipitation, snow; daily min/max temp,
# - OWM
# METAR, if you only want immediate conditions
GWeather.Provider.METAR
# METAR + NWS, if you want a forecast
# GWeather.Provider.METAR | GWeather.Provider.NWS
)
self.world = GWeather.Location.get_world()
def query_loc(self, loc: GWeather.Location) -> None:
'''
query the weather for some location, asynchronously.
after calling, poll the `try_...` methods to check for results.
'''
logger.debug(f"querying: {loc.get_coords()}")
self.info.set_location(loc)
self.info.update()
def try_get_celcius(self) -> float | None:
valid, temp = self.info.get_value_temp(GWeather.TemperatureUnit.CENTIGRADE)
logger.debug(f"try_get_celcius: valid={valid}, temp={temp}")
if not valid: temp = None
return temp
# potentially interesting methods on GWeather.Info:
# - get_conditions # returns '-'
# - get_forecast_list # forecast as a list of GWeather.Info instances (daily if IWIN; hourly if NWS)
# - get_sky # like 'Clear sky'
# - get_sunrise, get_sunset # like '1310', '0304' (utc time)
# - get_symbolic_icon_name # like 'weather-clear-night-symbolic'
# - get_temp_min, get_temp_max # returns '-'
# - get_temp_summary() # same as get_temp()
# - get_update() # like 'Thu, Aug 24 / 1300'
# - get_wind() # like 'North / 13.0 km/h'
# - get_visibility() # like '16093m'
# - get_weather_summary() # like 'Seattle-Tacoma International Airport: Clear sky'
class TopLevel:
"""
this class acts as the "event loop" which glib apps expect.
caller sets up a "work queue" of everything they want to do, then calls `run`.
glib calls `poll` in a loop, and each time we try to work through another item in the work_queue.
when the work_queue is empty, exit glib's main loop & return to the caller (from `run`).
"""
def __init__(self):
self._loop = GLib.MainLoop()
self.source = WeatherSource()
self.work_queue = []
def enqueue(self, op) -> None:
self.work_queue.append(op)
def run(self) -> None:
self.enqueue(ExitOp())
GLib.idle_add(self.poll)
self._loop.run()
def poll(self) -> bool:
work = self.work_queue[0]
if isinstance(work, QueryOp):
del self.work_queue[0]
self.source.query_loc(work.loc)
elif isinstance(work, PrintTempOp):
temp = self.source.try_get_celcius()
if temp is not None:
del self.work_queue[0]
print(f"{int(temp)}°C")
elif isinstance(work, DiagnosticsOp):
del self.work_queue[0]
# GWeather does transparent caching so that we don't usually hit the web
last_update = self.source.info.get_update()
logger.debug(f"last update: {last_update}")
elif isinstance(work, ExitOp):
logger.debug("quitting GLib MainLoop")
self.source.info.store_cache()
self._loop.quit()
elif isinstance(work, IdleOp):
del self.work_queue[0]
logger.debug("micro sleep")
time.sleep(0.1)
else:
assert False, f"unknown work: {work}"
# micro sleep so we don't peg CPU
# TODO: i'm sure there's a better way than all of this
time.sleep(0.05)
# re-queue this idle fn
return True
# operations:
# think of these as public methods on the `TopLevel` class,
# except abstracted as values for the sake of glib's event loop.
class QueryOp:
def __init__(self, loc: GWeather.Location):
self.loc = loc
class PrintTempOp:
pass
class DiagnosticsOp:
pass
class IdleOp:
pass
class ExitOp:
pass
def main():
logging.basicConfig()
parser = argparse.ArgumentParser(description="acquire weather information for user display")
parser.add_argument(
'--station-code',
default='KSEA',
help='4-letter METAR weather station code for where we want to know weather\n '
'to find your station see here: <https://aviationweather.gov/metar>'
)
parser.add_argument('--break-before', action='store_true', help='drop into a REPL before do anything (for debugging)')
parser.add_argument('--break-after', action='store_true', help='drop into a REPL after completing the work (for debugging)')
parser.add_argument('--verbose', action='store_true', help='enable verbose logging')
args = parser.parse_args()
if args.verbose:
logger.setLevel(logging.DEBUG)
GLib.log_set_debug_enabled(True)
toplevel = TopLevel()
here = GWeather.Location.find_by_station_code(toplevel.source.world, args.station_code)
if args.break_before:
code.interact(local=dict(**globals(), **locals()))
toplevel.enqueue(QueryOp(here))
toplevel.enqueue(PrintTempOp())
toplevel.enqueue(DiagnosticsOp())
# for _ in range(300): # for debugging...
# toplevel.enqueue(IdleOp())
toplevel.run()
if args.break_after:
code.interact(local=dict(**globals(), **locals()))
if __name__ == '__main__':
main()

View File

@@ -1,14 +1,19 @@
{ pkgs { pkgs
, bash
, lib , lib
, makeWrapper , makeWrapper
, python3 , python3
, stdenv , stdenv
, zsh
}: }:
let let
inherit (builtins) attrNames attrValues concatStringsSep foldl' map typeOf; inherit (builtins) attrNames attrValues concatStringsSep foldl' map typeOf;
inherit (lib) concatMapAttrs; inherit (lib) concatMapAttrs;
bash' = bash;
pkgs' = pkgs; pkgs' = pkgs;
python3' = python3;
zsh' = zsh;
# create an attrset of # create an attrset of
# <name> = expected string in the nix-shell invocation # <name> = expected string in the nix-shell invocation
# <value> = package to provide # <value> = package to provide
@@ -74,33 +79,33 @@ in rec {
); );
# `mkShell` specialization for `nix-shell -i bash` scripts. # `mkShell` specialization for `nix-shell -i bash` scripts.
mkBash = { pname, pkgs ? {}, srcPath ? pname, ...}@attrs: mkBash = { pname, pkgs ? {}, srcPath ? pname, bash ? bash', ...}@attrs:
let let
pkgsAsAttrs = pkgsToAttrs "" pkgs' pkgs; pkgsAsAttrs = pkgsToAttrs "" pkgs' pkgs;
pkgsEnv = attrValues pkgsAsAttrs; pkgsEnv = attrValues pkgsAsAttrs;
pkgExprs = attrNames pkgsAsAttrs; pkgExprs = attrNames pkgsAsAttrs;
in mkShell ({ in mkShell ({
inherit pkgsEnv pkgExprs; inherit pkgsEnv pkgExprs;
interpreter = "${pkgs'.bash}/bin/bash"; interpreter = "${bash}/bin/bash";
} // (removeAttrs attrs [ "pkgs" ]) } // (removeAttrs attrs [ "bash" "pkgs" ])
); );
# `mkShell` specialization for `nix-shell -i zsh` scripts. # `mkShell` specialization for `nix-shell -i zsh` scripts.
mkZsh = { pname, pkgs ? {}, srcPath ? pname, ...}@attrs: mkZsh = { pname, pkgs ? {}, srcPath ? pname, zsh ? zsh', ...}@attrs:
let let
pkgsAsAttrs = pkgsToAttrs "" pkgs' pkgs; pkgsAsAttrs = pkgsToAttrs "" pkgs' pkgs;
pkgsEnv = attrValues pkgsAsAttrs; pkgsEnv = attrValues pkgsAsAttrs;
pkgExprs = attrNames pkgsAsAttrs; pkgExprs = attrNames pkgsAsAttrs;
in mkShell ({ in mkShell ({
inherit pkgsEnv pkgExprs; inherit pkgsEnv pkgExprs;
interpreter = "${pkgs'.zsh}/bin/zsh"; interpreter = "${zsh}/bin/zsh";
} // (removeAttrs attrs [ "pkgs" ]) } // (removeAttrs attrs [ "pkgs" "zsh" ])
); );
# `mkShell` specialization for invocations of `nix-shell -p "python3.withPackages (...)"` # `mkShell` specialization for invocations of `nix-shell -p "python3.withPackages (...)"`
# pyPkgs argument is parsed the same as pkgs, except that names are assumed to be relative to `"ps"` if specified in list form. # pyPkgs argument is parsed the same as pkgs, except that names are assumed to be relative to `"ps"` if specified in list form.
# TODO: rename to `mkPython3` for consistency with e.g. `mkBash` # TODO: rename to `mkPython3` for consistency with e.g. `mkBash`
mkPython3Bin = { pname, pkgs ? {}, pyPkgs ? {}, srcPath ? pname, ... }@attrs: mkPython3Bin = { pname, pkgs ? {}, pyPkgs ? {}, srcPath ? pname, python3 ? python3', ... }@attrs:
let let
pyEnv = python3.withPackages (ps: attrValues ( pyEnv = python3.withPackages (ps: attrValues (
pkgsToAttrs "ps." ps pyPkgs pkgsToAttrs "ps." ps pyPkgs
@@ -118,6 +123,6 @@ in rec {
inherit pkgsEnv pkgExprs; inherit pkgsEnv pkgExprs;
interpreter = pyEnv.interpreter; interpreter = pyEnv.interpreter;
interpreterName = "python3"; interpreterName = "python3";
} // (removeAttrs attrs [ "pkgs" "pyPkgs" ]) } // (removeAttrs attrs [ "pkgs" "pyPkgs" "python3" ])
); );
} }

View File

@@ -1,24 +0,0 @@
diff --git a/setup_config_version.sh b/setup_config_version.sh
index fde40c1..6386014 100755
--- a/setup_config_version.sh
+++ b/setup_config_version.sh
@@ -8,7 +8,7 @@ case "$1" in
exit
esac
-case "$(busybox head -n1 "$1")" in
+case "$(head -n1 "$1")" in
"#"*)
comment="#"
;;
@@ -23,7 +23,7 @@ case "$(busybox head -n1 "$1")" in
;;
esac
-busybox md5sum "$1" | \
- busybox cut -d" " -f1 | \
- busybox xargs -I{} busybox sed -i "2i$comment configversion: {}" \
+md5sum "$1" | \
+ cut -d" " -f1 | \
+ xargs -I{} sed -i "2i$comment configversion: {}" \
"$1"

View File

@@ -1,58 +0,0 @@
commit bf0057011777b91ef5af005fb4e984b4b9b71c7b
Author: Colin <colin@uninsane.org>
Date: 2023-07-15 21:35:45 +0000
sxmo_wmmenu: respect SXMO_WORKSPACE_WRAPPING
sxmo_wm.sh uses the `SXMO_WORKSPACE_WRAPPING` variable to control
relative movements. for example, set this to "5" and then the "Next
Workspace" option in the switch menu will cycle WS 1 -> 2 ... -> 5 -> 1.
same for one- and two-finger left/right swipe to switch/move workspaces.
however, absolute movements (via the move menu) only allowed moving to
WS 1-4. a user with non-default `SXMO_WORKSPACE_WRAPPING` could move a
window from WS 5 to WS 4 with this menu, but not from WS 4 back to WS 5.
this patch brings consistency by using `SXMO_WORKSPACE_WRAPPING`
anywhere we would otherwise assume the number of possible workspaces.
diff --git a/scripts/core/sxmo_wmmenu.sh b/scripts/core/sxmo_wmmenu.sh
index 3d40b31..d3c1db6 100755
--- a/scripts/core/sxmo_wmmenu.sh
+++ b/scripts/core/sxmo_wmmenu.sh
@@ -12,6 +12,12 @@
set -e
+_movetowssubmenu() {
+ for ws in $(seq "${SXMO_WORKSPACE_WRAPPING:-4}"); do
+ printf "%s Move to WS %s\n" "$ws" "$ws"
+ done
+}
+
# A menu which allows to move windows or toggle floating.
swaymovemenu() {
CHOICES="$(cat <<EOF
@@ -22,10 +28,7 @@ $icon_arl Move Left
$icon_arr Move Right
$icon_wn2 Toggle Floating
$icon_ac1 Move Scratchpad
-1 Move to WS 1
-2 Move to WS 2
-3 Move to WS 3
-4 Move to WS 4
+$(_movetowssubmenu)
EOF
)"
@@ -125,10 +128,7 @@ dwmwmmenu() {
CHOICES="$(
cat <<EOF
$icon_cls Close Menu
-1 Move to WS 1
-2 Move to WS 2
-3 Move to WS 3
-4 Move to WS 4
+$(_movetowssubmenu)
$icon_rld Shift stack
$icon_grd Toggle Layout
EOF

View File

@@ -1,56 +0,0 @@
diff --git a/configs/default_hooks/sxmo_hook_apps.sh b/configs/default_hooks/sxmo_hook_apps.sh
index ba70a31..9f5a129 100755
--- a/configs/default_hooks/sxmo_hook_apps.sh
+++ b/configs/default_hooks/sxmo_hook_apps.sh
@@ -31,6 +31,7 @@ write_line_app audacity "$icon_mic Audacity" "audacity"
write_line_app gnome-calculator "$icon_clc Calculator" "gnome-calculator"
write_line_app calcurse "$icon_clk Calcurse" "sxmo_terminal.sh calcurse"
write_line_app cmus "$icon_mus Cmus" "sxmo_terminal.sh cmus"
+write_line_app cozy "$icon_mus Cozy" "com.github.geigi.cozy"
write_line_app dino "$icon_msg Dino" "GDK_SCALE=1 dino"
write_line_app dolphin "$icon_dir Dolphin" "dolphin"
write_line_app emacs "$icon_edt Emacs (Terminal)" "sxmo_terminal.sh emacs -nw"
@@ -54,19 +55,25 @@ write_line_app giara "$icon_red Giara" "giara"
write_line_app gnome-chess "$icon_chs Gnome Chess" "gnome-chess"
write_line_app gomuks "$icon_msg Gomuks" "sxmo_terminal.sh gomuks"
write_line_app gpodder "$icon_rss gPodder" "gpodder"
+write_line_app gthumb "$icon_img gThumb" "gthumb"
write_line_app gucharmap "$icon_inf Gucharmap" "gucharmap"
write_line_app hexchat "$icon_msg Hexchat" "hexchat"
write_line_app htop "$icon_cfg Htop" "sxmo_terminal.sh htop"
write_line_app irssi "$icon_msg Irssi" "sxmo_terminal.sh irssi"
write_line_app ii "$icon_msg Ii" "sxmo_terminal.sh ii"
write_line_app ipython "$icon_trm IPython" "sxmo_terminal.sh ipython"
+write_line_app jellyfinmediaplayer "$icon_mvi Jellyfin" "jellyfinmediaplayer"
write_line_app kasts "$icon_rss Kasts" "kasts"
write_line_app kmail "$icon_eml KMail" "kmail"
+write_line_app komikku "$icon_bok Komikku" "komikku"
write_line_app kontact "$icon_msg Kontact" "kontact"
write_line_app konversation "$icon_msg Konversation" "konversation"
+write_line_app koreader "$icon_bok KOReader" "koreader"
write_line_app kwrite "$icon_edt Kwrite" "kwrite"
write_line_app lagrange "$icon_glb Lagrange" "lagrange"
+write_line_app lemoa "$icon_grp Lemoa" "lemoa"
write_line_app lf "$icon_dir Lf" "sxmo_terminal.sh lf"
+write_line_app librewolf "$icon_glb Librewolf" "librewolf"
write_line_app lollypop "$icon_mus Lollypop" "lollypop"
write_line_app luakit "$icon_glb Luakit" "luakit"
write_line_app marble "$icon_map Marble" "marble"
@@ -97,6 +104,7 @@ write_line_app senpai "$icon_msg Senpai" "sxmo_terminal.sh senpai"
write_line_app sic "$icon_msg Sic" "sxmo_terminal.sh sic"
([ "$SXMO_WM" = dwm ] && command -v st >/dev/null) && \
write_line "$icon_trm St" "st -e $SHELL"
+write_line_app sublime-music "$icon_mus Sublime Music" "sublime-music"
write_line_app surf "$icon_glb Surf" "surf"
write_line_app syncthing "$icon_rld Syncthing" "syncthing"
write_line_app telegram-desktop "$icon_tgm Telegram" "telegram-desktop"
@@ -104,7 +112,9 @@ write_line_app termite "$icon_trm Termite" "termite -e $SHELL"
write_line_app thunar "$icon_dir Thunar" "sxmo_terminal.sh thunar"
write_line_app thunderbird "$icon_eml Thunderbird" "thunderbird"
write_line_app com.github.bleakgrey.tootle "$icon_msg Tootle" "com.github.bleakgrey.tootle"
+write_line_app re.sonny.Tangram "$icon_glb Tangram" "re.sonny.Tangram"
write_line_app totem "$icon_mvi Totem" "totem"
+write_line_app dev.geopjr.Tuba "$icon_grp Tuba" "dev.geopjr.Tuba"
write_line_app tuir "$icon_red Tuir" "sxmo_terminal.sh tuir"
write_line_app tut "$icon_msg Tut" "sxmo_terminal.sh tut"
write_line_app waydroid "$icon_and Waydroid" "waydroid show-full-ui"

View File

@@ -0,0 +1,182 @@
{ stdenv
, bash
, bc
, bemenu
, bonsai
, brightnessctl
, buildPackages
, busybox
, conky
, coreutils
, curl
, dbus
, fetchgit
, fetchpatch
, gitUpdater
, gnugrep
, gojq
, grim
, inotify-tools
, j4-dmenu-desktop
, jq
, lib
, libnotify
, libxml2
, lisgd
, makeBinaryWrapper
, mako
, mepo
, modemmanager
, nettools
, playerctl
, procps
, pulseaudio
, rsync
, scdoc
, sfeed
, slurp
, superd
, sway
, swayidle
, wob
, wl-clipboard
, wtype
, wvkbd
, xdg-user-dirs
, xdotool
, xrdb
, version
, rev ? version
, hash ? ""
, patches ? []
}:
let
# anything which any sxmo script or default hook in this package might invoke
runtimeDeps = [
bc # also in busybox
bemenu
bonsai
brightnessctl
conky
curl
dbus
# dmenu # or dmenu-wayland? only used on x11?
gnugrep # also in busybox
gojq
grim
inotify-tools
j4-dmenu-desktop
jq
libnotify
libxml2.bin # for xmllint; sxmo_weather.sh, sxmo_surf_linkset.sh
lisgd
mako
mepo # mepo_ui_central_menu.sh
modemmanager # mmcli
nettools # netstat
playerctl
procps # pgrep
pulseaudio # pactl
sfeed
slurp # for sxmo_screenshot.sh
superd
sway
swayidle
wl-clipboard # for wl-copy; sxmo_screenshot.sh
wob
wtype # for sxmo_type
wvkbd
xdg-user-dirs
xrdb # for sxmo_xinit AND sxmo_winit
# X11 only?
xdotool
];
in
stdenv.mkDerivation rec {
pname = "sxmo-utils";
inherit version;
src = fetchgit {
url = "https://git.sr.ht/~mil/sxmo-utils";
inherit rev hash;
};
inherit patches;
postPatch = ''
# allow sxmo to source its init file
sed -i "s@/etc/profile\.d/sxmo_init.sh@$out/etc/profile.d/sxmo_init.sh@" scripts/core/*.sh
# remove absolute paths
substituteInPlace scripts/core/sxmo_version.sh \
--replace "/usr/bin/" ""
# let superd find sxmo service binaries at runtime via PATH
# TODO: replace with fully-qualified paths
sed -i 's:ExecStart=/usr/bin/:ExecStart=/usr/bin/env :' configs/superd/services/*.service
# install udev rules to where nix expects
substituteInPlace Makefile \
--replace "/usr/lib/udev/rules.d" "/etc/udev/rules.d"
# avoid relative paths in udev rules
substituteInPlace configs/udev/90-sxmo.rules \
--replace "/bin/chgrp" "${coreutils}/bin/chgrp" \
--replace "/bin/chmod" "${coreutils}/bin/chmod"
'';
nativeBuildInputs = [
makeBinaryWrapper
scdoc
];
buildInputs = [ bash ]; # needed here so stdenv's `patchShebangsAuto` hook sets the right interpreter
makeFlags = [
"PREFIX=${placeholder "out"}"
"SYSCONFDIR=${placeholder "out"}/etc"
"DESTDIR="
"OPENRC=0"
];
preInstall = ''
# busybox is used by setup_config_version.sh, but placing it in nativeBuildInputs breaks the nix builder
PATH="$PATH:${buildPackages.busybox}/bin"
'';
# we don't wrap sxmo_common.sh or sxmo_init.sh
# which is unfortunate, for non-sxmo-utils files that might source those.
# if that's a problem, could inject a PATH=... line into them with sed.
postInstall = ''
for f in \
$out/bin/*.sh \
$out/share/sxmo/default_hooks/desktop/sxmo_hook_*.sh \
$out/share/sxmo/default_hooks/one_button_e_reader/sxmo_hook_*.sh \
$out/share/sxmo/default_hooks/three_button_touchscreen/sxmo_hook_*.sh \
$out/share/sxmo/default_hooks/sxmo_hook_*.sh \
; do
case $(basename $f) in
(sxmo_common.sh|sxmo_deviceprofile_*.sh|sxmo_hook_icons.sh|sxmo_init.sh)
# these are sourced by other scripts: don't wrap them else the `exec` in the wrapper breaks the outer script
;;
(*)
wrapProgram "$f" \
--prefix PATH : "${lib.makeBinPath runtimeDeps}"
;;
esac
done
'';
passthru = {
providedSessions = [ "sxmo" "swmo" ];
updateScript = gitUpdater { };
};
meta = {
homepage = "https://git.sr.ht/~mil/sxmo-utils";
description = "Contains the scripts and small C programs that glues the sxmo enviroment together";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ colinsane ];
platforms = lib.platforms.linux;
};
}

View File

@@ -1,90 +1,9 @@
{ stdenv { callPackage
, bc
, bemenu
, bonsai
, conky
, coreutils
, dbus
, fetchgit
, fetchpatch , fetchpatch
, gitUpdater
, gnugrep
, gojq
, grim
, inotify-tools
, j4-dmenu-desktop
, jq
, lib
, libnotify
, lisgd
, makeBinaryWrapper
, mako
, mepo
, modemmanager
, nettools
, playerctl
, procps
, pulseaudio
, rsync
, scdoc
, sfeed
, superd
, sway
, swayidle
, wob
, wvkbd
, xdg-user-dirs
, xdotool
}: }:
let let
# anything which any sxmo script or default hook in this package might invoke patches = {
runtimeDeps = [ merged = [
bc
bemenu
bonsai
conky
dbus
# dmenu # or dmenu-wayland? only used on x11?
gnugrep
gojq
grim
inotify-tools
j4-dmenu-desktop
jq
libnotify
lisgd
mako
mepo # mepo_ui_central_menu.sh
modemmanager # mmcli
nettools # netstat
playerctl
procps # pgrep
pulseaudio # pactl
sfeed
superd
sway
swayidle
wob
wvkbd
xdg-user-dirs
# X11 only?
xdotool
];
in
stdenv.mkDerivation rec {
pname = "sxmo-utils";
version = "1.14.2";
src = fetchgit {
url = "https://git.sr.ht/~mil/sxmo-utils";
rev = version;
hash = "sha256-1bGCUhf/bt9I8BjG/G7sjYBzLh28iZSC20ml647a3J4=";
};
patches = [
# needed for basic use:
(fetchpatch { (fetchpatch {
# merged post 1.14.2 # merged post 1.14.2
# [1/2] sxmo_init: behave well when user's primary group differs from their name # [1/2] sxmo_init: behave well when user's primary group differs from their name
@@ -103,21 +22,44 @@ stdenv.mkDerivation rec {
# i only care about patch no. 2 # i only care about patch no. 2
# [1/2] suspend toggle: silence rm failure noise # [1/2] suspend toggle: silence rm failure noise
# [2/2] config: fix keyboard files location # [2/2] config: fix keyboard files location
name = "multipatch: 42880";
url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42880/mbox"; url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42880/mbox";
hash = "sha256-tAMPBb6vwzj1dFMTEaqrcCJU6FbQirwZgB0+tqW3rQA="; hash = "sha256-tAMPBb6vwzj1dFMTEaqrcCJU6FbQirwZgB0+tqW3rQA=";
}) })
./0004-no-busybox.patch
# wanted to fix/silence some non-fatal errors
./0005-system-audio.patch
./0007-workspace-wrapping.patch
# personal (but upstreamable) preferences:
(fetchpatch { (fetchpatch {
# merged post 1.14.2 # merged post 1.14.2
# sxmo_hook_lock: allow configuration of auto-screenoff timeout v1 name = "Switch from light to brightnessctl";
url = "https://git.sr.ht/~mil/sxmo-utils/commit/d0384a7caed036d25228fa3279c36c0230795e4a.patch";
hash = "sha256-/UlcuEI5cJnsqRuZ1zWWzR4dyJw/zYeB1rtJWFeSGEE=";
})
(fetchpatch {
# merged post 1.14.2
name = "sxmo_hook_lock: allow configuration of auto-screenoff timeout v1";
url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42443/mbox"; url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42443/mbox";
hash = "sha256-c4VySbVJgsbh2h+CnCgwWWe5WkAregpYFqL8n3WRXwY="; hash = "sha256-c4VySbVJgsbh2h+CnCgwWWe5WkAregpYFqL8n3WRXwY=";
}) })
(fetchpatch {
# merged post 1.14.2
name = "sxmo_wmmenu: respect SXMO_WORKSPACE_WRAPPING";
url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42698/mbox";
hash = "sha256-TrTlrthrpYdIMC8/RCMNaB8PcGQgtya/h2/uLNQDeWs=";
})
(fetchpatch {
# merged ~2023/08/22
name = "Make config gesture toggle persistent";
url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42876/mbox";
hash = "sha256-Oa0MI0Kt9Xgl5L1KarHI6Yn4+vpRxUSujB1iY4hlK9c=";
})
(fetchpatch {
# merged ~2023/08/29
# [1/2] Makefile: obey PREFIX when installing udev rules
# [2/2] Makefile: use SYSCONFDIR instead of hardcoding /etc
name = "44110-multipatch-makefile-nixos";
url = "https://lists.sr.ht/~mil/sxmo-devel/patches/44110/mbox";
hash = "sha256-jXtwgOVGSjwWj7a36F6P+e63lKvk4OmFIzxTkf9yZMs=";
})
];
unmerged = [
# (fetchpatch { # (fetchpatch {
# XXX: doesn't apply cleanly to 1.14.2 release # XXX: doesn't apply cleanly to 1.14.2 release
# # Don't wait for led or status bar in state change hooks # # Don't wait for led or status bar in state change hooks
@@ -125,80 +67,41 @@ stdenv.mkDerivation rec {
# url = "https://lists.sr.ht/~mil/sxmo-devel/patches/43109/mbox"; # url = "https://lists.sr.ht/~mil/sxmo-devel/patches/43109/mbox";
# hash = "sha256-4uR2u6pa62y6SaRHYRn15YGDPILAs7py0mPbAjsgwM4="; # hash = "sha256-4uR2u6pa62y6SaRHYRn15YGDPILAs7py0mPbAjsgwM4=";
# }) # })
(fetchpatch { (fetchpatch {
# Make config gesture toggle persistent name = "sxmo_migrate: add option to disable configversion checks";
url = "https://lists.sr.ht/~mil/sxmo-devel/patches/42876/mbox"; url = "https://lists.sr.ht/~mil/sxmo-devel/patches/44155/mbox";
hash = "sha256-Oa0MI0Kt9Xgl5L1KarHI6Yn4+vpRxUSujB1iY4hlK9c="; hash = "sha256-ZcUD2UWPM8PxGM9TBnGe8JCJgMC72OZYzctDf2o7Ub0=";
}) })
## these might or might not be upstream-worthy
./0104-full-auto-rotate.patch ./0104-full-auto-rotate.patch
./0105-more-apps.patch
# ./0106-no-restart-lisgd.patch # ./0106-no-restart-lisgd.patch
## not upstreamable
# let NixOS manage the audio daemons (pulseaudio/pipewire)
./0005-system-audio.patch
]; ];
# these don't apply cleanly to the stable release; only to latest
postPatch = '' unmerged-tip-only = [
# allow sxmo to source its init file # TODO: send these upstream
sed -i "s@/etc/profile\.d/sxmo_init.sh@$out/etc/profile.d/sxmo_init.sh@" scripts/core/*.sh (fetchpatch {
# remove absolute paths name = "sxmo_hook_apps: add a few";
substituteInPlace scripts/core/sxmo_version.sh \ url = "https://git.uninsane.org/colin/sxmo-utils/commit/d6c17a89e1b7bc74d0ba34629fd5db393e5f560b.patch";
--replace "/usr/bin/" "" hash = "sha256-b12p7RTnAqTVfHpYLkNTwuo12KDznYCYJUEJAIES/1I=";
})
# let superd find sxmo service binaries at runtime via PATH
# TODO: replace with fully-qualified paths
sed -i 's:ExecStart=/usr/bin/:ExecStart=/usr/bin/env :' configs/superd/services/*.service
# install udev rules to where nix expects
substituteInPlace Makefile \
--replace "/usr/lib/udev/rules.d" "/etc/udev/rules.d"
# avoid relative paths in udev rules
substituteInPlace configs/udev/90-sxmo.rules \
--replace "/bin/chgrp" "${coreutils}/bin/chgrp" \
--replace "/bin/chmod" "${coreutils}/bin/chmod"
'';
nativeBuildInputs = [
makeBinaryWrapper
scdoc
]; ];
installFlags = [
"OPENRC=0"
"DESTDIR=$(out)"
"PREFIX="
];
# we don't wrap sxmo_common.sh or sxmo_init.sh
# which is unfortunate, for non-sxmo-utils files that might source though.
# if that's a problem, could inject a PATH=... line into them with sed.
postInstall = ''
for f in \
$out/bin/*.sh \
$out/share/sxmo/default_hooks/desktop/sxmo_hook_*.sh \
$out/share/sxmo/default_hooks/one_button_e_reader/sxmo_hook_*.sh \
$out/share/sxmo/default_hooks/three_button_touchscreen/sxmo_hook_*.sh \
$out/share/sxmo/default_hooks/sxmo_hook_*.sh \
; do
case $(basename $f) in
(sxmo_common.sh|sxmo_deviceprofile_*.sh|sxmo_hook_icons.sh|sxmo_init.sh)
# these are sourced by other scripts: don't wrap them else the `exec` in the wrapper breaks the outer script
;;
(*)
wrapProgram "$f" \
--prefix PATH : "${lib.makeBinPath runtimeDeps}"
;;
esac
done
'';
passthru = {
providedSessions = [ "sxmo" "swmo" ];
updateScript = gitUpdater { };
}; };
in {
meta = { stable = callPackage ./common.nix {
homepage = "https://git.sr.ht/~mil/sxmo-utils"; version = "1.14.2";
description = "Contains the scripts and small C programs that glues the sxmo enviroment together"; hash = "sha256-1bGCUhf/bt9I8BjG/G7sjYBzLh28iZSC20ml647a3J4=";
license = lib.licenses.mit; patches = patches.merged ++ patches.unmerged;
maintainers = with lib.maintainers; [ colinsane ]; };
platforms = lib.platforms.linux; latest = callPackage ./common.nix {
version = "unstable-2023-08-29";
rev = "871caa7394d2deda6aaff89af0fea9f6de773c2e";
hash = "sha256-TnRit0W/Racm92AwoEuSIJiOtu2XBUd3IsQoPrtshvk=";
patches = patches.unmerged ++ patches.unmerged-tip-only;
}; };
} }

View File

@@ -21,10 +21,14 @@ let
### ADDITIONAL PACKAGES ### ADDITIONAL PACKAGES
alsa-ucm-conf-sane = callPackage ./additional/alsa-ucm-conf-sane { }; alsa-ucm-conf-sane = callPackage ./additional/alsa-ucm-conf-sane { };
bonsai = unpatched.bonsai or (callPackage ./additional/bonsai { }); # TODO: move target flags to upstream PR and re-enable this bonsai
# bonsai = unpatched.bonsai or (callPackage ./additional/bonsai { });
bonsai = callPackage ./additional/bonsai { };
bootpart-uefi-x86_64 = callPackage ./additional/bootpart-uefi-x86_64 { }; bootpart-uefi-x86_64 = callPackage ./additional/bootpart-uefi-x86_64 { };
cargoDocsetHook = callPackage ./additional/cargo-docset/hook.nix { }; cargoDocsetHook = callPackage ./additional/cargo-docset/hook.nix { };
chatty-latest = callPackage ./additional/chatty-latest { }; chatty-latest = callPackage ./additional/chatty-latest { };
eg25-control = callPackage ./additional/eg25-control { };
eg25-manager = callPackage ./additional/eg25-manager { };
feeds = lib.recurseIntoAttrs (callPackage ./additional/feeds { }); feeds = lib.recurseIntoAttrs (callPackage ./additional/feeds { });
lemoa = callPackage ./additional/lemoa { }; lemoa = callPackage ./additional/lemoa { };
jellyfin-media-player-qt6 = callPackage ./additional/jellyfin-media-player-qt6 { }; jellyfin-media-player-qt6 = callPackage ./additional/jellyfin-media-player-qt6 { };
@@ -40,14 +44,20 @@ let
koreader-from-src = callPackage ./additional/koreader-from-src { }; koreader-from-src = callPackage ./additional/koreader-from-src { };
ldd-aarch64 = callPackage ./additional/ldd-aarch64 { }; ldd-aarch64 = callPackage ./additional/ldd-aarch64 { };
lightdm-mobile-greeter = callPackage ./additional/lightdm-mobile-greeter { }; lightdm-mobile-greeter = callPackage ./additional/lightdm-mobile-greeter { };
linux-manjaro = callPackage ./additional/linux-manjaro { };
linux-megous = callPackage ./additional/linux-megous { }; linux-megous = callPackage ./additional/linux-megous { };
mcg = callPackage ./additional/mcg { };
mpv-uosc-latest = callPackage ./additional/mpv-uosc-latest { }; mpv-uosc-latest = callPackage ./additional/mpv-uosc-latest { };
mx-sanebot = callPackage ./additional/mx-sanebot { }; mx-sanebot = callPackage ./additional/mx-sanebot { };
phog = callPackage ./additional/phog { };
rtl8723cs-firmware = callPackage ./additional/rtl8723cs-firmware { }; rtl8723cs-firmware = callPackage ./additional/rtl8723cs-firmware { };
sane-scripts = lib.recurseIntoAttrs (callPackage ./additional/sane-scripts { }); sane-scripts = lib.recurseIntoAttrs (callPackage ./additional/sane-scripts { });
sane-weather = callPackage ./additional/sane-weather { };
static-nix-shell = callPackage ./additional/static-nix-shell { }; static-nix-shell = callPackage ./additional/static-nix-shell { };
sublime-music-mobile = callPackage ./additional/sublime-music-mobile { }; sublime-music-mobile = callPackage ./additional/sublime-music-mobile { };
sxmo-utils = callPackage ./additional/sxmo-utils { }; sxmo-utils' = lib.recurseIntoAttrs (callPackage ./additional/sxmo-utils { });
sxmo-utils = sxmo-utils'.stable;
sxmo-utils-latest = sxmo-utils'.latest;
tow-boot-pinephone = callPackage ./additional/tow-boot-pinephone { }; tow-boot-pinephone = callPackage ./additional/tow-boot-pinephone { };
tree-sitter-nix-shell = callPackage ./additional/tree-sitter-nix-shell { }; tree-sitter-nix-shell = callPackage ./additional/tree-sitter-nix-shell { };
unftp = callPackage ./additional/unftp { }; unftp = callPackage ./additional/unftp { };
@@ -104,12 +114,13 @@ let
helix = callPackage ./patched/helix { inherit (unpatched) helix; }; helix = callPackage ./patched/helix { inherit (unpatched) helix; };
ibus = callPackage ./patched/ibus { inherit (unpatched) ibus; };
# jackett doesn't allow customization of the bind address: this will probably always be here. # jackett doesn't allow customization of the bind address: this will probably always be here.
jackett = callPackage ./patched/jackett { inherit (unpatched) jackett; }; jackett = callPackage ./patched/jackett { inherit (unpatched) jackett; };
libgweather = callPackage ./patched/libgweather { inherit (unpatched) libgweather; };
komikku = callPackage ./patched/komikku { inherit (unpatched) komikku; }; # modemmanager = callPackage ./patched/modemmanager { inherit (unpatched) modemmanager; };
phoc = callPackage ./patched/phoc { inherit (unpatched) phoc; };
### PYTHON PACKAGES ### PYTHON PACKAGES

View File

@@ -11,12 +11,15 @@ let
}; };
in in
helix.overrideAttrs (upstream: { helix.overrideAttrs (upstream: {
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
rsync
];
configurePhase = (upstream.configurePhase or "") + '' configurePhase = (upstream.configurePhase or "") + ''
cat ${languages} >> languages.toml cat ${languages} >> languages.toml
substituteAllInPlace languages.toml substituteAllInPlace languages.toml
${rsync}/bin/rsync -arv ${tree-sitter-nix-shell.generated}/ runtime/grammars/sources/nix-shell/ rsync -arv ${tree-sitter-nix-shell.generated}/ runtime/grammars/sources/nix-shell/
${rsync}/bin/rsync -arv ${tree-sitter-nix-shell}/queries/ runtime/queries/nix-shell/ rsync -arv ${tree-sitter-nix-shell}/queries/ runtime/queries/nix-shell/
# helix tries to delete the sources during installPhase # helix tries to delete the sources during installPhase
chmod -R +w runtime/grammars/sources/nix-shell chmod -R +w runtime/grammars/sources/nix-shell

View File

@@ -0,0 +1,21 @@
diff --git a/data/dconf/make-dconf-override-db.sh b/data/dconf/make-dconf-override-db.sh
index 32cb1530..4ce36bc1 100755
--- a/data/dconf/make-dconf-override-db.sh
+++ b/data/dconf/make-dconf-override-db.sh
@@ -12,10 +12,6 @@ export XDG_CACHE_HOME="$TMPDIR/cache"
export GSETTINGS_SCHEMA_DIR="$TMPDIR/schemas"
mkdir -p $XDG_CONFIG_HOME $XDG_CACHE_HOME $GSETTINGS_SCHEMA_DIR
-eval `dbus-launch --sh-syntax`
-
-trap cleanup EXIT
-
cleanup() {
test $? -eq 0 && exit
rm -rf $TMPDIR; kill $DBUS_SESSION_BUS_PID
@@ -57,5 +53,3 @@ if [ -d $TMPDIR/cache/gvfs ] ; then
umount $TMPDIR/cache/gvfs
fi
rm -rf $TMPDIR
-
-kill $DBUS_SESSION_BUS_PID

View File

@@ -0,0 +1,18 @@
diff --git a/configure.ac b/configure.ac
index 392cc581..6d5750dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -345,11 +345,7 @@ fi
AC_SUBST(X11_PREFIX)
# Check locale dir for Compose files.
-AC_CHECK_FILE($X11_PREFIX/share/X11/locale/locale.dir,
- X11_LOCALEDATADIR="$X11_PREFIX/share/X11/locale",
- [AC_CHECK_FILE($X11_PREFIX/lib/X11/locale/locale.dir,
- X11_LOCALEDATADIR="$X11_PREFIX/lib/X11/locale",
- X11_LOCALEDATADIR="$(datadir)/X11/locale")])
+X11_LOCALEDATADIR="$X11_PREFIX/share/X11/locale"
AC_SUBST(X11_LOCALEDATADIR)
if test x"$enable_wayland" = x"yes"; then

View File

@@ -0,0 +1,58 @@
{ ibus
, buildPackages
, fetchFromGitHub
, gobject-introspection
, lib
, libdbusmenu-gtk3
, pkg-config
, pkgs
, stdenv
, ...
}@attrs:
let
isCross = !(stdenv.buildPlatform.canExecute stdenv.hostPlatform);
in
(ibus.override
(removeAttrs attrs [ "ibus" "libdbusmenu-gtk3" "pkgs" ] )
).overrideAttrs (upstream: rec {
# compared to 1.5.28, this version supports better cross compilation
version = "1.5.29-rc1";
src = fetchFromGitHub {
owner = "ibus";
repo = "ibus";
rev = version;
hash = "sha256-stUWAGtsQRq+g/68OKuYqHgNxZBGzGC6VgJ+IwuAkx8=";
};
patches = [(builtins.head upstream.patches)] ++ [
# this patch is in nixpkgs 1.5.28, but doesn't cleanly apply to this current version
./build-without-dbus-launch.patch
# AC_CHECK_FILE has an explicit guard against cross compiling, which is silly if you think about it for more than a second.
./configure-no-ac-check-file.patch
];
# vapigen (vala) is nativeBuildInputs, so fix the PKG_CONFIG ibus uses to find it.
# ibus does an extra sanity check with `PKG_CHECK_EXISTS`, but that doesn't support
# PKG_CONFIG_FOR_BUILD, so turn its error into just a warning.
postPatch = (upstream.postPatch or "") + lib.optionalString isCross ''
substituteInPlace m4/vapigen.m4 \
--replace PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG_FOR_BUILD \
--replace 'PKG_CONFIG ' 'PKG_CONFIG_FOR_BUILD ' \
--replace 'AC_MSG_ERROR([$vapigen_pkg not found])' 'AC_MSG_WARN([$vapigen_pkg not found])'
'';
configureFlags = upstream.configureFlags ++ [
"--enable-vala"
];
# to debug:
# makeFlags = upstream.makeFlags ++ [ "V=1" ];
depsBuildBuild = (upstream.depsBuildBuild or []) ++ [
buildPackages.stdenv.cc
pkg-config
];
buildInputs = upstream.buildInputs ++ [
libdbusmenu-gtk3
];
})

View File

@@ -1,19 +0,0 @@
{ komikku
, fetchFromGitLab
, fetchpatch2
}:
komikku.overrideAttrs (upstream: {
# src = fetchFromGitLab {
# owner = "valos";
# repo = "Komikku";
# rev = "7dcf2b3d0ba685396872780b1ce75d01cbe02ebe";
# hash = "sha256-LzgHPuIpxy0ropiNycdxZP6onjK2JpMRqkkdmJGA4nE=";
# };
patches = (upstream.patches or []) ++ [
(fetchpatch2 {
url = "https://git.uninsane.org/colin/mirror-komikku/commit/318fc0c975ba84ca4dcff405bc1bb8f5895bc5a6.diff";
hash = "sha256-mn81hCt5xrypJMOOiCOg8NthLjglXntTDsYpcdCg0E8=";
})
];
passthru.unpatched = komikku;
})

Some files were not shown because too many files have changed in this diff Show More