Migrate A2-D1 (Mac Mini) to A1-D1 (clicks server)

Signed-off-by: Skyler Grey <skyler3665@gmail.com>
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..f53c9c6
--- /dev/null
+++ b/.envrc
@@ -0,0 +1 @@
+use_flake .#
diff --git a/.gitignore b/.gitignore
index dbc3671..4f58826 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-secrets/.decrypted~*
\ No newline at end of file
+secrets/.decrypted~*
+.direnv/
diff --git a/flake.lock b/flake.lock
index a7fb059..e275b5e 100644
--- a/flake.lock
+++ b/flake.lock
@@ -91,6 +91,22 @@
         "type": "github"
       }
     },
+    "nixpkgs-clicksforms": {
+      "locked": {
+        "lastModified": 1685573264,
+        "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "380be19fbd2d9079f677978361792cb25e8a3635",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-22.05",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "nixpkgs-privatebin": {
       "locked": {
         "lastModified": 1691328775,
@@ -145,6 +161,7 @@
         "flake-utils": "flake-utils",
         "home-manager": "home-manager",
         "nixpkgs": "nixpkgs_2",
+        "nixpkgs-clicksforms": "nixpkgs-clicksforms",
         "nixpkgs-privatebin": "nixpkgs-privatebin",
         "scalpel": "scalpel",
         "sops-nix": "sops-nix"
diff --git a/flake.nix b/flake.nix
index e6b6c6f..7d0d732 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,6 +2,7 @@
   description = "A flake to deploy and configure Clicks' NixOS server";
 
   inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
+  inputs.nixpkgs-clicksforms.url = "github:nixos/nixpkgs/nixos-22.05";
   inputs.flake-utils.url = "github:numtide/flake-utils";
   inputs.deploy-rs.url = "github:serokell/deploy-rs";
   inputs.home-manager.url = "github:nix-community/home-manager/release-23.05";
@@ -126,6 +127,7 @@
                       }
                       "${./services}/${service}"
                     ];
+                    extraSpecialArgs = { inherit (inputs) nixpkgs-clicksforms; inherit system; };
                   });
             };
           in
@@ -175,6 +177,10 @@
         profilesOrder = [ "system" ];
       };
 
+      devShells.x86_64-linux.default = pkgs.mkShell {
+        packages = [ pkgs.deploy-rs ];
+      };
+
       formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixpkgs-fmt;
     };
 }
diff --git a/services/clicksforms/default.nix b/services/clicksforms/default.nix
new file mode 100644
index 0000000..e1cd51d
--- /dev/null
+++ b/services/clicksforms/default.nix
@@ -0,0 +1,26 @@
+{ nixpkgs-clicksforms, system, config, lib, ... }: let
+  pkgsOld = nixpkgs-clicksforms.legacyPackages.${system};
+in { 
+  home.packages = [
+    (pkgsOld.python3.withPackages (pyPkgs: with pyPkgs; [
+      databases
+      sqlalchemy
+      orm
+      typesystem
+      (pyPkgs.callPackage ./discordpy.nix {})
+      aiohttp
+      fastapi
+      aiosqlite
+      uvicorn
+      validators
+      (
+        pyPkgs.fetchPypi {
+          pname = "jishaku";
+          version = "2.5.1";
+          hash = lib.fakeSha256;
+        }
+      )
+      slowapi
+    ]))
+  ];
+}
diff --git a/services/clicksforms/discordpy.nix b/services/clicksforms/discordpy.nix
new file mode 100644
index 0000000..83aed0f
--- /dev/null
+++ b/services/clicksforms/discordpy.nix
@@ -0,0 +1,64 @@
+{ lib
+, aiohttp
+, buildPythonPackage
+, fetchFromGitHub
+, libopus
+, pynacl
+, pythonOlder
+, withVoice ? true
+, ffmpeg
+}:
+
+buildPythonPackage rec {
+  pname = "discord.py";
+  version = "2.0.0";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.8";
+
+  src = fetchFromGitHub {
+    owner = "Rapptz";
+    repo = pname;
+    rev = "refs/tags/v${version}";
+    hash = "sha256-Rh3gijm67LVyOaliP7w3YwKviKydnxXvu4snNrM5H1c=";
+  };
+
+  propagatedBuildInputs = [
+    aiohttp
+  ] ++ lib.optionals withVoice [
+    libopus
+    pynacl
+    ffmpeg
+  ];
+
+  patchPhase = ''
+    substituteInPlace "discord/opus.py" \
+      --replace "ctypes.util.find_library('opus')" "'${libopus}/lib/libopus.so.0'"
+  '' + lib.optionalString withVoice ''
+    substituteInPlace "discord/player.py" \
+      --replace "executable='ffmpeg'" "executable='${ffmpeg}/bin/ffmpeg'"
+  '';
+
+  # Only have integration tests with discord
+  doCheck = false;
+
+  pythonImportsCheck = [
+    "discord"
+    "discord.file"
+    "discord.member"
+    "discord.user"
+    "discord.state"
+    "discord.guild"
+    "discord.webhook"
+    "discord.ext.commands.bot"
+  ];
+
+  meta = with lib; {
+    description = "Python wrapper for the Discord API";
+    homepage = "https://discordpy.rtfd.org/";
+    changelog = "https://github.com/Rapptz/discord.py/blob/v${version}/docs/whats_new.rst";
+    license = licenses.mit;
+    maintainers = with maintainers; [ minion3665 ];
+  };
+}
+
diff --git a/services/darknosis/default.nix b/services/darknosis/default.nix
new file mode 100644
index 0000000..4691474
--- /dev/null
+++ b/services/darknosis/default.nix
@@ -0,0 +1 @@
+{ pkgs, config, lib, ... }: { }
diff --git a/services/tontine/default.nix b/services/tontine/default.nix
new file mode 100644
index 0000000..4691474
--- /dev/null
+++ b/services/tontine/default.nix
@@ -0,0 +1 @@
+{ pkgs, config, lib, ... }: { }