Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{
2 stdenv,
3 fetchurl,
4 lib,
5 nodejs,
6 node-pre-gyp,
7 node-gyp,
8 python3,
9 util-linux,
10 ffmpeg-headless,
11
12 # Current derivation only supports linux-x86_64 (contributions welcome, without libTensorflow builtin webassembly can be used)
13 useLibTensorflow ? stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform.isLinux,
14
15 ncVersion,
16}:
17let
18 latestVersionForNc = {
19 "31" = {
20 version = "9.0.3";
21 appHash = "sha256-G7SDE72tszifozfT3vNxHW6WmMqQKhrSayQVANQaMbs=";
22 modelHash = "sha256-dB4ot/65xisR700kUXg3+Y+SkrpQO4mWrFfp+En0QEE=";
23 };
24 "30" = {
25 version = "8.2.1";
26 appHash = "sha256-xSJbfL5HI1bo5KYvk/ssEjSUsWF1hFQkl5MOm/kXYDE=";
27 modelHash = "sha256-O1gh3d0MGQOHUbrIyX3f+R7lGJ7+i8tTmrnfKlczrsk=";
28 };
29 };
30 currentVersionInfo =
31 latestVersionForNc.${ncVersion}
32 or (throw "recognize currently does not support nextcloud version ${ncVersion}");
33in
34stdenv.mkDerivation rec {
35 pname = "nextcloud-app-recognize";
36 inherit (currentVersionInfo) version;
37
38 srcs = [
39 (fetchurl {
40 url = "https://github.com/nextcloud/recognize/releases/download/v${version}/recognize-${version}.tar.gz";
41 hash = currentVersionInfo.appHash;
42 })
43
44 (fetchurl {
45 url = "https://github.com/nextcloud/recognize/archive/refs/tags/v${version}.tar.gz";
46 hash = currentVersionInfo.modelHash;
47 })
48 ]
49 ++ lib.optionals useLibTensorflow [
50 (fetchurl {
51 # For version see LIBTENSORFLOW_VERSION in https://github.com/tensorflow/tfjs/blob/master/tfjs-node/scripts/deps-constants.js
52 url = "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-2.9.1.tar.gz";
53 hash = "sha256-f1ENJUbj214QsdEZRjaJAD1YeEKJKtPJW8pRz4KCAXM=";
54 })
55 ];
56
57 unpackPhase = ''
58 # Merge the app and the models from github
59 tar -xzpf "${builtins.elemAt srcs 0}" recognize
60 tar -xzpf "${builtins.elemAt srcs 1}" -C recognize --strip-components=1 recognize-${version}/models
61 ''
62 + lib.optionalString useLibTensorflow ''
63 # Place the tensorflow lib at the right place for building
64 tar -xzpf "${builtins.elemAt srcs 2}" -C recognize/node_modules/@tensorflow/tfjs-node/deps
65 '';
66
67 postPatch = ''
68 # Make it clear we are not reading the node in settings
69 sed -i "/'node_binary'/s:'""':'Nix Controlled':" recognize/lib/Service/SettingsService.php
70
71 # Replace all occurrences of node (and check that we actually removed them all)
72 test "$(grep "get[a-zA-Z]*('node_binary'" recognize/lib/**/*.php | wc -l)" -gt 0
73 substituteInPlace recognize/lib/**/*.php \
74 --replace-quiet "\$this->settingsService->getSetting('node_binary')" "'${lib.getExe nodejs}'" \
75 --replace-quiet "\$this->config->getAppValueString('node_binary', '""')" "'${lib.getExe nodejs}'" \
76 --replace-quiet "\$this->config->getAppValueString('node_binary')" "'${lib.getExe nodejs}'"
77 test "$(grep "get[a-zA-Z]*('node_binary'" recognize/lib/**/*.php | wc -l)" -eq 0
78
79 # Skip trying to install it... (less warnings in the log)
80 sed -i '/public function run/areturn ; //skip' recognize/lib/Migration/InstallDeps.php
81
82 ln -s ${lib.getExe ffmpeg-headless} recognize/node_modules/ffmpeg-static/ffmpeg
83 '';
84
85 nativeBuildInputs = lib.optionals useLibTensorflow [
86 nodejs
87 node-pre-gyp
88 node-gyp
89 python3
90 util-linux
91 ];
92
93 buildPhase = lib.optionalString useLibTensorflow ''
94 cd recognize
95
96 # Install tfjs dependency
97 export CPPFLAGS="-I${lib.getDev nodejs}/include/node -Ideps/include"
98 cd node_modules/@tensorflow/tfjs-node
99 node-pre-gyp install --prefer-offline --build-from-source --nodedir=${nodejs}
100 cd -
101
102 # Test tfjs returns exit code 0
103 node src/test_libtensorflow.js
104 cd ..
105 '';
106
107 installPhase = ''
108 approot="$(dirname $(dirname $(find -path '*/appinfo/info.xml' | head -n 1)))"
109 if [ -d "$approot" ]; then
110 mv "$approot/" $out
111 chmod -R a-w $out
112 fi
113 '';
114
115 meta = with lib; {
116 license = licenses.agpl3Only;
117 maintainers = with maintainers; [ beardhatcode ];
118 longDescription = ''
119 Nextcloud app that does Smart media tagging and face recognition with on-premises machine learning models.
120 This app goes through your media collection and adds fitting tags, automatically categorizing your photos and music.
121 '';
122 homepage = "https://apps.nextcloud.com/apps/recognize";
123 description = "Smart media tagging for Nextcloud: recognizes faces, objects, landscapes, music genres";
124 changelog = "https://github.com/nextcloud/recognize/blob/v${version}/CHANGELOG.md";
125 };
126}