commit f7218b50056a423b16416b52056008a546d8f201 Author: h7x4 Date: Mon Jan 2 02:18:49 2023 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2be92b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..69977ef --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 h7x4 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b89c08e --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +[![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) + +# maunium-stickerpicker-nix + +Nix wrapper for [maunium/stickerpicker][maunium-stickerpicker] + +## Usage: + +Here's an example of a stickerpicker + +```nix +myStickerPicker = createStickerPicker { + homeserver = "https://my.matrix.server"; + userId = "@stickerbot:my.matrix.server"; + # You should probably encrypt this with either agenix, sops-nix or whatever else + accessTokenFile = ./stickerbot_access_token.txt; + sha256 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + packs = [ + { + type = "chatsticker"; + name = "pompom-tao3"; + } + { + type = "directory"; + src = ./myHomemadeStickers; + } + ]; +}; +``` + +Afterwards, you can easily host it in an nginx config + +```nix +{ ... }: +{ +services.nginx.enable = true; +services.nginx.virtualHosts."stickers.myhost.org" = { + root = myStickerPicker; + }; +} +``` + +## List of available fetchers + +| Site | Type Name |Required Arguments | +|------|-----------|-------------------| +| `` | `directory` | `src` (path to a local dir with image files) | +| https://chatsticker.com | `chatsticker` | `name` (see url) | + +## Some notes + +To use this, leave the `sha256` empty at first, build the stickerspicker with whatever stickers you'd like, and paste the `sha256` from the error message back into your code. + +Normally, [maunium/stickerpicker][maunium-stickerpicker] would cache the stickers in a config file, and reuse the config file on the next run in order not to. +This does not work with Nix' determinism. +Thus every time you want to add just 1 more stickerpack (or any other kind of edit), this will reupload all stickers. +In order to make it easier to delete all sticker once in a while, I would recommend creating a separate user (I've called mine `stickerbot`), whose only purpose is to be the owner of a bunch of sticker media files. +Whenever you want to clean up the media store, just delete all the media file of `stickerbot` (**THIS WILL BREAK OLDER MESSAGES**) + +[maunium-stickerpicker]: https://github.com/maunium/stickerpicker diff --git a/createStickerPicker.nix b/createStickerPicker.nix new file mode 100644 index 0000000..3b3b170 --- /dev/null +++ b/createStickerPicker.nix @@ -0,0 +1,85 @@ +{ + lib, + maunium-stickerpicker, + stickerpicker-tools, + fetchers, + + callPackage, + stdenvNoCC, + writeText, + + cacert, + ... +}: +{ + homeserver ? "https://matrix.org", + userId, + accessTokenFile, + packs, + hash ? "", + sha256 ? "" +}: +with lib; +if !(all builtins.isAttrs packs) then + throw "createStickerPack: not all packs are attrsets" +else if !(all (x: x ? "type") packs) then + throw ''createStickerPack: Not all packs have the "type" attribute'' +else if !(all (x: builtins.isString x.type) packs) then + throw ''createStickerPack: Not all packs have a "type" attribute of type string'' +else let + invalidTypes = filter (x: !(fetchers ? "${x.type}-build")) packs; +in if invalidTypes != [ ] then throw '' + createStickerPack: Not all packs have a valid "type" attribute. + + The following types does not exist: + ${concatStringsSep "\n" (map (x: " ${x.type}") invalidTypes)} +'' +else let + stickerDownloadInstructions = pipe packs [ + (map (x: fetchers."${x.type}-build" x)) + (concatStringsSep "\n") + ]; + + stickerDownloadDependencies = pipe packs [ + (map (x: fetchers."${x.type}-deps")) + builtins.concatLists + ]; + + config-json = writeText "stickerpicker-config.json" '' + { + "homeserver": "${homeserver}", + "user_id": "${userId}", + "access_token": "${fileContents accessTokenFile}" + } + ''; +in stdenvNoCC.mkDerivation { + name = "stickerpicker"; + src = maunium-stickerpicker; + + outputHashAlgo = if hash != "" then null else "sha256"; + outputHashMode = "recursive"; + outputHash = if hash != "" then + hash + else if sha256 != "" then + sha256 + else + fakeSha256; + + buildInputs = [ + stickerpicker-tools + cacert + ] ++ stickerDownloadDependencies; + + buildPhase = '' + mkdir images + IMG_DIR="$(pwd)/images" + STICKERPACKS_DIR="$(pwd)/web/packs" + STICKER_CONFIG="${config-json}" + + ${stickerDownloadInstructions} + ''; + + installPhase = '' + mv web $out + ''; +} diff --git a/fetchers.nix b/fetchers.nix new file mode 100644 index 0000000..949a94f --- /dev/null +++ b/fetchers.nix @@ -0,0 +1,50 @@ +{ pkgs, lib, ... }: let + baseFetcher = { instructions, type, title, id ? "", dir }: let + dirname = "${type}-${dir}"; + in '' + pushd $IMG_DIR + mkdir '${dirname}' + pushd '${dirname}' + + ${instructions} + + popd + + sticker-pack \ + --config "$STICKER_CONFIG" \ + --add-to-index "$STICKERPACKS_DIR" \ + --title '${title}' \ + '${dirname}' + + popd + ''; +in { + directory-deps = [ ]; + directory-build = { src, id ? "", title ? "", ... }: baseFetcher { + inherit id title; + type = "directory"; + dir = builtins.baseNameOf src; + instructions = '' + ln -s ${src}/* . + ''; + }; + + chatsticker-deps = with pkgs; [ wget html-xml-utils ]; + chatsticker-build = { name, id ? "", title ? "", ... }: baseFetcher { + inherit id title; + type = "chatstickers"; + dir = name; + instructions = '' + wget "https://chatsticker.com/sticker/${name}" -O raw.html + hxnormalize -l 240 -x raw.html > normalized.html + cat normalized.html | hxselect -s '\n' -c ".img-fluid::attr(src)" > images.txt; + sed -i 's|;compress=true||' images.txt + + for url in $(cat images.txt); do + wget $url + done + + rm raw.html normalized.html images.txt + ''; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..3395430 --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "maunium-stickerpicker": { + "flake": false, + "locked": { + "lastModified": 1668509918, + "narHash": "sha256-5Kbok9vJIlOti+ikpJXv2skdADhQQTjX5mVmBTM0wGU=", + "owner": "maunium", + "repo": "stickerpicker", + "rev": "f59406a47a6778cd402e656ffb64f667335f665a", + "type": "github" + }, + "original": { + "owner": "maunium", + "repo": "stickerpicker", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1672441588, + "narHash": "sha256-jx5kxOyeObnVD44HRebKYL3cjWrcKhhcDmEYm0/naDY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6a0d2701705c3cf6f42c15aa92b7885f1f8a477f", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "maunium-stickerpicker": "maunium-stickerpicker", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2537bc3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,41 @@ +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-22.11"; + + maunium-stickerpicker = { + url = "github:maunium/stickerpicker"; + flake = false; + }; + }; + + outputs = { self, nixpkgs, maunium-stickerpicker }: let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + fetchers = pkgs.callPackage ./fetchers.nix { }; + createStickerPicker = pkgs.callPackage ./createStickerPicker.nix { + inherit maunium-stickerpicker fetchers; + inherit (self.packages.${system}) stickerpicker-tools; + }; + in { + inherit createStickerPicker; + + packages.${system} = { + default = self.packages.${system}.stickerpicker-tools; + stickerpicker-tools = pkgs.python3Packages.buildPythonPackage { + name = "stickerpicker-tools"; + src = maunium-stickerpicker; + + propagatedBuildInputs = with pkgs.python3Packages; [ + aiohttp + yarl + pillow + telethon + cryptg + python-magic + pkgs.cacert + ]; + doCheck = false; + }; + }; + }; +}