Merge pull request #202935 from huantianad/activitywatch
This commit is contained in:
commit
bc71ecaa8a
2957
pkgs/applications/office/activitywatch/Cargo.lock
generated
Normal file
2957
pkgs/applications/office/activitywatch/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
16
pkgs/applications/office/activitywatch/commit-hash.patch
Normal file
16
pkgs/applications/office/activitywatch/commit-hash.patch
Normal file
|
@ -0,0 +1,16 @@
|
|||
diff --git a/vue.config.js b/vue.config.js
|
||||
index 02c0699..0c4a014 100644
|
||||
--- a/vue.config.js
|
||||
+++ b/vue.config.js
|
||||
@@ -4,10 +4,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const { argv } = require('yargs');
|
||||
|
||||
// get git info from command line
|
||||
-const _COMMIT_HASH = require('child_process')
|
||||
- .execSync('git rev-parse --short HEAD')
|
||||
- .toString()
|
||||
- .trim();
|
||||
+const _COMMIT_HASH = "@commit_hash@";
|
||||
console.info('Commit hash:', _COMMIT_HASH);
|
||||
|
||||
module.exports = {
|
238
pkgs/applications/office/activitywatch/default.nix
Normal file
238
pkgs/applications/office/activitywatch/default.nix
Normal file
|
@ -0,0 +1,238 @@
|
|||
{ lib
|
||||
, fetchFromGitHub
|
||||
, rustPlatform
|
||||
, makeWrapper
|
||||
, pkg-config
|
||||
, perl
|
||||
, openssl
|
||||
, python3
|
||||
, wrapQtAppsHook
|
||||
, qtbase
|
||||
, qtsvg
|
||||
, xdg-utils
|
||||
, substituteAll
|
||||
, buildNpmPackage
|
||||
}:
|
||||
|
||||
let
|
||||
version = "0.12.2";
|
||||
sources = fetchFromGitHub {
|
||||
owner = "ActivityWatch";
|
||||
repo = "activitywatch";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-IvRXfxTOSgBVlxy4SVij+POr7KgvXTEjGN3lSozhHkY=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
in
|
||||
rec {
|
||||
aw-watcher-afk = python3.pkgs.buildPythonApplication {
|
||||
pname = "aw-watcher-afk";
|
||||
inherit version;
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
src = "${sources}/aw-watcher-afk";
|
||||
|
||||
nativeBuildInputs = [
|
||||
python3.pkgs.poetry-core
|
||||
];
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
aw-client
|
||||
xlib
|
||||
pynput
|
||||
];
|
||||
|
||||
pythonImportsCheck = [ "aw_watcher_afk" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Watches keyboard and mouse activity to determine if you are AFK or not (for use with ActivityWatch)";
|
||||
homepage = "https://github.com/ActivityWatch/aw-watcher-afk";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
};
|
||||
|
||||
aw-watcher-window = python3.pkgs.buildPythonApplication {
|
||||
pname = "aw-watcher-window";
|
||||
inherit version;
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
src = "${sources}/aw-watcher-window";
|
||||
|
||||
nativeBuildInputs = [
|
||||
python3.pkgs.poetry-core
|
||||
];
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
aw-client
|
||||
xlib
|
||||
];
|
||||
|
||||
pythonImportsCheck = [ "aw_watcher_window" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Cross-platform window watcher (for use with ActivityWatch)";
|
||||
homepage = "https://github.com/ActivityWatch/aw-watcher-window";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
};
|
||||
|
||||
aw-qt = python3.pkgs.buildPythonApplication {
|
||||
pname = "aw-qt";
|
||||
inherit version;
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
src = "${sources}/aw-qt";
|
||||
|
||||
nativeBuildInputs = [
|
||||
python3.pkgs.poetry-core
|
||||
wrapQtAppsHook
|
||||
];
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
aw-core
|
||||
qtbase
|
||||
qtsvg # Rendering icons in the trayicon menu
|
||||
pyqt6
|
||||
click
|
||||
];
|
||||
|
||||
# Prevent double wrapping
|
||||
dontWrapQtApps = true;
|
||||
|
||||
makeWrapperArgs = [
|
||||
"--suffix PATH : ${lib.makeBinPath [ xdg-utils ]}"
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
sed -E 's#PyQt6 = "6.3.1"#PyQt6 = "^6.4.0"#g' -i pyproject.toml
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
install -D resources/aw-qt.desktop $out/share/applications/aw-qt.desktop
|
||||
|
||||
# For the actual tray icon, see
|
||||
# https://github.com/ActivityWatch/aw-qt/blob/8ec5db941ede0923bfe26631acf241a4a5353108/aw_qt/trayicon.py#L211-L218
|
||||
install -D media/logo/logo.png $out/${python3.sitePackages}/media/logo/logo.png
|
||||
|
||||
# For .desktop file and your desktop environment
|
||||
install -D media/logo/logo.svg $out/share/icons/hicolor/scalable/apps/activitywatch.svg
|
||||
install -D media/logo/logo.png $out/share/icons/hicolor/512x512/apps/activitywatch.png
|
||||
install -D media/logo/logo-128.png $out/share/icons/hicolor/128x128/apps/activitywatch.png
|
||||
'';
|
||||
|
||||
preFixup = ''
|
||||
makeWrapperArgs+=(
|
||||
"''${qtWrapperArgs[@]}"
|
||||
)
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "aw_qt" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Tray icon that manages ActivityWatch processes, built with Qt";
|
||||
homepage = "https://github.com/ActivityWatch/aw-qt";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
};
|
||||
|
||||
aw-server-rust = rustPlatform.buildRustPackage {
|
||||
pname = "aw-server-rust";
|
||||
inherit version;
|
||||
|
||||
src = "${sources}/aw-server-rust";
|
||||
|
||||
cargoLock = {
|
||||
lockFile = ./Cargo.lock;
|
||||
outputHashes = {
|
||||
"rocket_cors-0.6.0-alpha1" = "sha256-GuMekgnsyuOg6lMiVvi4TwMba4sAFJ/zkgrdzSeBrv0=";
|
||||
};
|
||||
};
|
||||
|
||||
# Bypass rust nightly features not being available on rust stable
|
||||
RUSTC_BOOTSTRAP = 1;
|
||||
|
||||
patches = [
|
||||
# Override version string with hardcoded value as it may be outdated upstream.
|
||||
(substituteAll {
|
||||
src = ./override-version.patch;
|
||||
version = sources.rev;
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
makeWrapper
|
||||
pkg-config
|
||||
perl
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
openssl
|
||||
];
|
||||
|
||||
postFixup = ''
|
||||
wrapProgram "$out/bin/aw-server" \
|
||||
--prefix XDG_DATA_DIRS : "$out/share"
|
||||
|
||||
mkdir -p "$out/share/aw-server"
|
||||
ln -s "${aw-webui}" "$out/share/aw-server/static"
|
||||
'';
|
||||
|
||||
preCheck = ''
|
||||
# Fake home folder for tests that use ~/.cache and ~/.local/share
|
||||
export HOME="$TMPDIR"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "High-performance implementation of the ActivityWatch server, written in Rust";
|
||||
homepage = "https://github.com/ActivityWatch/aw-server-rust";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
mainProgram = "aw-server";
|
||||
platforms = platforms.linux;
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
};
|
||||
|
||||
aw-webui = buildNpmPackage {
|
||||
pname = "aw-webui";
|
||||
inherit version;
|
||||
|
||||
src = "${sources}/aw-server-rust/aw-webui";
|
||||
|
||||
npmDepsHash = "sha256-yds2P2PKfTB6yUGnc+P73InV5+MZP9kmz2ZS4CRqlmA=";
|
||||
|
||||
patches = [
|
||||
# Hardcode version to avoid the need to have the Git repo available at build time.
|
||||
(substituteAll {
|
||||
src = ./commit-hash.patch;
|
||||
commit_hash = sources.rev;
|
||||
})
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mv dist $out
|
||||
cp media/logo/logo.{png,svg} $out/static/
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
npm test
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "A web-based UI for ActivityWatch, built with Vue.js";
|
||||
homepage = "https://github.com/ActivityWatch/aw-webui/";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
diff --git a/aw-server/src/endpoints/mod.rs b/aw-server/src/endpoints/mod.rs
|
||||
index a080d2a..0411d1e 100644
|
||||
--- a/aw-server/src/endpoints/mod.rs
|
||||
+++ b/aw-server/src/endpoints/mod.rs
|
||||
@@ -76,11 +76,10 @@ async fn root_favicon(state: &State<ServerState>) -> Option<NamedFile> {
|
||||
fn server_info(config: &State<AWConfig>, state: &State<ServerState>) -> Json<Info> {
|
||||
#[allow(clippy::or_fun_call)]
|
||||
let hostname = gethostname().into_string().unwrap_or("unknown".to_string());
|
||||
- const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
|
||||
|
||||
Json(Info {
|
||||
hostname,
|
||||
- version: format!("v{} (rust)", VERSION.unwrap_or("(unknown)")),
|
||||
+ version: String::from("@version@ (rust)"),
|
||||
testing: config.testing,
|
||||
device_id: state.device_id.clone(),
|
||||
})
|
18
pkgs/applications/office/activitywatch/wrapper.nix
Normal file
18
pkgs/applications/office/activitywatch/wrapper.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{ lib
|
||||
, symlinkJoin
|
||||
, aw-server-rust
|
||||
, aw-qt
|
||||
, aw-watcher-afk
|
||||
, aw-watcher-window
|
||||
, extraWatchers ? [ ]
|
||||
}:
|
||||
|
||||
symlinkJoin {
|
||||
name = "activitywatch-${aw-server-rust.version}";
|
||||
paths = [
|
||||
aw-server-rust.out
|
||||
aw-qt.out
|
||||
aw-watcher-afk.out
|
||||
aw-watcher-window.out
|
||||
] ++ (lib.forEach extraWatchers (p: p.out));
|
||||
}
|
65
pkgs/development/python-modules/aw-client/default.nix
Normal file
65
pkgs/development/python-modules/aw-client/default.nix
Normal file
|
@ -0,0 +1,65 @@
|
|||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, pythonOlder
|
||||
, poetry-core
|
||||
, aw-core
|
||||
, requests
|
||||
, persist-queue
|
||||
, click
|
||||
, tabulate
|
||||
, typing-extensions
|
||||
, pytestCheckHook
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aw-client";
|
||||
version = "0.5.11";
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
# pypi distribution doesn't include tests, so build from source instead
|
||||
src = fetchFromGitHub {
|
||||
owner = "ActivityWatch";
|
||||
repo = "aw-client";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-5WKGRoZGY+QnnB1Jzlju5OmCJreYMD8am2kW3Wcjhlw=";
|
||||
};
|
||||
|
||||
disabled = pythonOlder "3.8";
|
||||
|
||||
nativeBuildInputs = [
|
||||
poetry-core
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
aw-core
|
||||
requests
|
||||
persist-queue
|
||||
click
|
||||
tabulate
|
||||
typing-extensions
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
# Only run this test, the others are integration tests that require
|
||||
# an instance of aw-server running in order to function.
|
||||
pytestFlagsArray = [ "tests/test_requestqueue.py" ];
|
||||
|
||||
preCheck = ''
|
||||
# Fake home folder for tests that write to $HOME
|
||||
export HOME="$TMPDIR"
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "aw_client" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Client library for ActivityWatch";
|
||||
homepage = "https://github.com/ActivityWatch/aw-client";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
}
|
69
pkgs/development/python-modules/aw-core/default.nix
Normal file
69
pkgs/development/python-modules/aw-core/default.nix
Normal file
|
@ -0,0 +1,69 @@
|
|||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, pythonOlder
|
||||
, poetry-core
|
||||
, jsonschema
|
||||
, peewee
|
||||
, appdirs
|
||||
, iso8601
|
||||
, rfc3339-validator
|
||||
, takethetime
|
||||
, strict-rfc3339
|
||||
, tomlkit
|
||||
, deprecation
|
||||
, timeslot
|
||||
, pytestCheckHook
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aw-core";
|
||||
version = "0.5.12";
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
# pypi distribution doesn't include tests, so build from source instead
|
||||
src = fetchFromGitHub {
|
||||
owner = "ActivityWatch";
|
||||
repo = "aw-core";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-DbugVMaQHlHpfbFEsM6kfpDL2VzRs0TDn9klWjAwz64=";
|
||||
};
|
||||
|
||||
disabled = pythonOlder "3.8";
|
||||
|
||||
nativeBuildInputs = [
|
||||
poetry-core
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
jsonschema
|
||||
peewee
|
||||
appdirs
|
||||
iso8601
|
||||
rfc3339-validator
|
||||
takethetime
|
||||
strict-rfc3339
|
||||
tomlkit
|
||||
deprecation
|
||||
timeslot
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
preCheck = ''
|
||||
# Fake home folder for tests that write to $HOME
|
||||
export HOME="$TMPDIR"
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "aw_core" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Core library for ActivityWatch";
|
||||
homepage = "https://github.com/ActivityWatch/aw-core";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mpl20;
|
||||
};
|
||||
}
|
44
pkgs/development/python-modules/persist-queue/default.nix
Normal file
44
pkgs/development/python-modules/persist-queue/default.nix
Normal file
|
@ -0,0 +1,44 @@
|
|||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchPypi
|
||||
, pythonOlder
|
||||
, msgpack
|
||||
, nose2
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "persist-queue";
|
||||
version = "0.8.0";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-vapNz8SyCpzh9cttoxFrbLj+N1J9mR/SQoVu8szNIY4=";
|
||||
};
|
||||
|
||||
disabled = pythonOlder "3.6";
|
||||
|
||||
nativeCheckInputs = [
|
||||
msgpack
|
||||
nose2
|
||||
];
|
||||
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
|
||||
# Don't run MySQL tests, as they require a MySQL server running
|
||||
rm persistqueue/tests/test_mysqlqueue.py
|
||||
|
||||
nose2
|
||||
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "persistqueue" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Thread-safe disk based persistent queue in Python";
|
||||
homepage = "https://github.com/peter-wangxu/persist-queue";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
};
|
||||
}
|
41
pkgs/development/python-modules/takethetime/default.nix
Normal file
41
pkgs/development/python-modules/takethetime/default.nix
Normal file
|
@ -0,0 +1,41 @@
|
|||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, pythonOlder
|
||||
, pytestCheckHook
|
||||
}:
|
||||
|
||||
buildPythonPackage {
|
||||
pname = "takethetime";
|
||||
version = "0.3.1";
|
||||
|
||||
# pypi distribution doesn't include tests, so build from source instead
|
||||
src = fetchFromGitHub {
|
||||
owner = "ErikBjare";
|
||||
repo = "TakeTheTime";
|
||||
rev = "b0042ac5b1cc9d3b70ef59167b094469ceb660dd";
|
||||
sha256 = "sha256-DwsMnP6G3BzOnINttaSC6QKkIKK5qyhUz+lN1DSvkw0=";
|
||||
};
|
||||
|
||||
disabled = pythonOlder "3.6";
|
||||
|
||||
nativeCheckInputs = [ pytestCheckHook ];
|
||||
|
||||
pytestFlagsArray = [ "tests/tests.py" ];
|
||||
|
||||
pythonImportsCheck = [ "takethetime" ];
|
||||
|
||||
# Latest release is v0.3.1 on pypi, but this version was not bumped in
|
||||
# the setup.py, causing packages that depend on v0.3.1 to fail to build.
|
||||
postPatch = ''
|
||||
substituteInPlace setup.py \
|
||||
--replace "version='0.3'" "version='0.3.1'"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Simple time taking library using context managers";
|
||||
homepage = "https://github.com/ErikBjare/TakeTheTime";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mit;
|
||||
};
|
||||
}
|
48
pkgs/development/python-modules/timeslot/default.nix
Normal file
48
pkgs/development/python-modules/timeslot/default.nix
Normal file
|
@ -0,0 +1,48 @@
|
|||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, pythonOlder
|
||||
, poetry-core
|
||||
, pytestCheckHook
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "timeslot";
|
||||
version = "0.1.2";
|
||||
|
||||
# pypi distribution doesn't include tests, so build from source instead
|
||||
src = fetchFromGitHub {
|
||||
owner = "ErikBjare";
|
||||
repo = pname;
|
||||
rev = "af35445e96cbb2f3fb671a75aac6aa93e4e7e7a6";
|
||||
sha256 = "sha256-GEhg2iMsYMfalT7L9TCd1KHU6oa/wTl5m3mRC0zOH9Q=";
|
||||
};
|
||||
|
||||
format = "pyproject";
|
||||
|
||||
disabled = pythonOlder "3.6";
|
||||
|
||||
nativeBuildInputs = [
|
||||
poetry-core
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
pytestFlagsArray = [
|
||||
# The pyproject.toml specifies the flag `--cov=timeslot`,
|
||||
# This causes an error when running without pytest-cov,
|
||||
# so use this flag to override that option, as we don't need coverage.
|
||||
"--override-ini addopts=''"
|
||||
];
|
||||
|
||||
pythonImportsCheck = [ "timeslot" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Data type for representing time slots with a start and end";
|
||||
homepage = "https://github.com/ErikBjare/timeslot";
|
||||
maintainers = with maintainers; [ huantian ];
|
||||
license = licenses.mit;
|
||||
};
|
||||
}
|
|
@ -28951,6 +28951,14 @@ with pkgs;
|
|||
|
||||
acorn = callPackage ../applications/networking/cluster/acorn { };
|
||||
|
||||
inherit (qt6Packages.callPackage ../applications/office/activitywatch { })
|
||||
aw-qt
|
||||
aw-server-rust
|
||||
aw-watcher-afk
|
||||
aw-watcher-window;
|
||||
|
||||
activitywatch = callPackage ../applications/office/activitywatch/wrapper.nix { };
|
||||
|
||||
adobe-reader = pkgsi686Linux.callPackage ../applications/misc/adobe-reader { };
|
||||
|
||||
adl = callPackage ../applications/video/adl { };
|
||||
|
|
|
@ -853,6 +853,10 @@ self: super: with self; {
|
|||
|
||||
avro-python3 = callPackage ../development/python-modules/avro-python3 { };
|
||||
|
||||
aw-client = callPackage ../development/python-modules/aw-client { };
|
||||
|
||||
aw-core = callPackage ../development/python-modules/aw-core { };
|
||||
|
||||
awacs = callPackage ../development/python-modules/awacs { };
|
||||
|
||||
awesome-slugify = callPackage ../development/python-modules/awesome-slugify { };
|
||||
|
@ -7348,6 +7352,8 @@ self: super: with self; {
|
|||
|
||||
persim = callPackage ../development/python-modules/persim { };
|
||||
|
||||
persist-queue = callPackage ../development/python-modules/persist-queue { };
|
||||
|
||||
persistent = callPackage ../development/python-modules/persistent { };
|
||||
|
||||
persisting-theory = callPackage ../development/python-modules/persisting-theory { };
|
||||
|
@ -11721,6 +11727,8 @@ self: super: with self; {
|
|||
|
||||
tailscale = callPackage ../development/python-modules/tailscale { };
|
||||
|
||||
takethetime = callPackage ../development/python-modules/takethetime { };
|
||||
|
||||
tank-utility = callPackage ../development/python-modules/tank-utility { };
|
||||
|
||||
tappy = callPackage ../development/python-modules/tappy { };
|
||||
|
@ -11991,6 +11999,8 @@ self: super: with self; {
|
|||
|
||||
timeout-decorator = callPackage ../development/python-modules/timeout-decorator { };
|
||||
|
||||
timeslot = callPackage ../development/python-modules/timeslot { };
|
||||
|
||||
timetagger = callPackage ../development/python-modules/timetagger { };
|
||||
|
||||
timezonefinder = callPackage ../development/python-modules/timezonefinder { };
|
||||
|
|
Loading…
Reference in a new issue